热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

面试常见算法排序查找算法

算法是程序员必被的一个技能,在面试中常常出现,下面总结了面试中出现的常见算法,这些算法程序员应该牢记在心中

算法是程序员必被的一个技能,在面试中常常出现,下面总结了面试中出现的常见算法,这些算法程序员应该牢记在心中,要非常熟练。

插入排序算法

原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。

要点:设立哨兵,作为临时存储和判断数组边界之用。

public class InsertSort {
private static void insertSort(int[] a) {
int j;
int tmp;
for (int i = 1; i tmp = a[i];
for (j = i; j > 0 && tmp a[j] = a[j - 1];
}
a[j] = tmp;
}
}
}

希尔排序算法

原理:又称增量缩小排序。先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。

要点:增量的选择以及排序最终以1为增量进行排序结束。

public class ShellSort {
private static void shellSort(int[] a) {
int j;
int tmp;
for (int gap = a.length / 2; gap >0; gap /= 2) {
for (int i = gap; i tmp = a[i];
for (j = i; j >= gap && tmp a[j] = a[j - gap];
}
a[j] = tmp;
}
}
}
}

冒泡排序算法

原理:将序列划分为无序和有序区,不断通过交换较大元素至无序区尾完成排序。

要点:设计交换判断条件,提前结束以排好序的序列循环。

public class BubbleSort {
private static void bubbleSort(int[] a) {
for (int i = 0; i for (int j = 0; j if (a[j] > a[j + 1]) {
swap(a, j, j + 1);
}
}
}
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
}

快速排序算法

原理:不断寻找一个序列的中点,然后对中点左右的序列递归的进行排序,直至全部序列排序完成,使用了分治的思想。

要点:递归、分治

public class QuickSort {
private static void quickSort(int[] a) {
quickSort(a, 0, a.length - 1);
}
private static void quickSort(int[] a, int left, int right) {
if (left int pivot = a[left];
int lo = left;
int hi = right;
while (lo while (lo = pivot) {
hi--;
}
a[lo] = a[hi];
while (lo lo++;
}
a[hi] = a[lo];
}
a[lo] = pivot;
quickSort(a, left, lo - 1);
quickSort(a, lo + 1, right);
}
}
}

简单选择排序算法

原理:将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序

public class SelectSort {
private static void selectSort(int[] a) {
int idx;
for (int i = 0; i idx = i;
for (int j = i + 1; j if (a[idx] > a[j]) {
idx = j;
}
}
swap(a, idx, i);
}
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
}

堆排序算法

原理:利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区。

要点:建堆、交换、调整堆

public class HeapSort {
private static void heapSort(int[] a) {
// 先创建大堆,从第一个非叶子结点开始调整,然后调整第二个非叶子结点...
for (int i = a.length / 2; i >= 0 ; i--) {
shiftDown(a, i, a.length);
}
// 调整大堆,将最大的元素调整到未排好序的部分的末尾
for (int i = a.length - 1; i > 0 ; i--) {
swap(a, 0, i);
shiftDown(a, 0, i);
}
}
private static void shiftDown(int[] a, int i, int n) {
int child;
int tmp;
for (tmp = a[i]; i * 2 + 1 child = i * 2 + 1;
if (child != n - 1 && a[child] child++;
}
if (tmp a[i] = a[child];
} else {
break;
}
}
a[i] = tmp;
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
}

归并排序算法

原理:将原序列划分为有序的两个序列,然后利用归并算法进行合并,合并之后即为有序序列。

要点:归并、分治

public class MergeSort {
private static void mergeSort(int[] a) {
int[] b = new int[a.length];
mergeSort(a, b, 0, a.length - 1);
}
private static void mergeSort(int[] a, int[] b, int left, int right) {
if (left int center = left + (right - left) / 2;
mergeSort(a, b, left, center);
mergeSort(a, b, center + 1, right);
merge(a, b, left, center + 1, right);
}
}
private static void merge(int[] a, int[] b, int leftPos, int rightPos, intrightEnd) {
int leftEnd = rightPos - 1;
int tempPos = leftPos;
int numElements = rightEnd - leftPos + 1;
while (leftPos <= leftEnd && rightPos <= rightEnd) {
if (a[leftPos] <= a[rightPos]) {
b[tempPos] = a[leftPos];
tempPos++;
leftPos++;
} else {
b[tempPos] = a[rightPos];
tempPos++;
rightPos++;
}
}
while (leftPos <= leftEnd) {
b[tempPos] = a[leftPos];
tempPos++;
leftPos++;
}
while (rightPos <= rightEnd) {
b[tempPos] = a[rightPos];
tempPos++;
rightPos++;
}
for (int i = 0; i a[rightEnd] = b[rightEnd];
}
}
}

二分查找算法

public class BinarySearch {
public static int binarySearch(int[] a, int v) {
int mid;
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
mid = lo + ((hi - lo) >>> 1); // 移位运算的优先级比较低,要用括号
if (a[mid] == v) { // 已经找到
return mid;
} else if (a[mid] lo = mid + 1;
} else { // 可能在左边
hi = mid - 1;
}
}
return -1; // 未找到
}
}


推荐阅读
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • PDF内容编辑的两种小方法,你知道怎么操作吗?
    本文介绍了两种PDF内容编辑的方法:迅捷PDF编辑器和Adobe Acrobat DC。使用迅捷PDF编辑器,用户可以通过选择需要更改的文字内容并设置字体形式、大小和颜色来编辑PDF文件。而使用Adobe Acrobat DC,则可以通过在软件中点击编辑来编辑PDF文件。PDF文件的编辑可以帮助办公人员进行文件内容的修改和定制。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
author-avatar
fjfzfisher
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有