面试常考8种排序算法的总结
来源:互联网 发布:windows桌面主题手机版 编辑:程序博客网 时间:2024/05/20 23:59
(1)插入排序
直接插入排序是一种较简单的排序方法;
算法思想:
将一个记录插入到已排好的有序表中,从而得到一个新的记录数加一的有序表;
示例:{3,45,66,97,1,6,65}
初始关键字 :
(3) 45 66 97 1 6 65
i=2: (45) (3 45) 66 97 1 6 65
i=3: (66) (3 45 66) 97 1 6 65
i=4: (97) (3 45 66 97) 1 6 65
i=5: (1) (1 3 45 66 97) 6 65
i=6: (6) (1 3 6 45 66 97) 65
i=7: (65) (1 3 6 45 65 66 97)
插入排序代码如下:
void insert_Sort(int *arr, int size){//arr 需要传入的数组,size数组的大小 for (int i = 1; i < size; i++)//进行size-1次插入 { int j = 0; while (arr[j] < arr[i] && j < i)//找到插入的位置 { j++; } if (i != j) { int tmp = arr[i]; for (int k = i; k>j; k--) arr[k] = arr[k-1]; arr[j] = tmp; } }}
(2)希尔排序
希尔排序属于插入排序类的方法;
算法思想:
先将整个待排序序列分割成若干子序列分别进行直接插入排序,
待整个序列的记录基本有序的时候,再对全体记录进行一次直接插入排序。
希尔排序代码
void shell_Sort(int *arr, int size){ int i, j, step; for (step = size / 2; step > 0; step /= 2) { for (i = step; i < size;i++) for (j = i - step; j >= 0 && arr[j]>arr[j + step]; j -= step) swap(arr[j],arr[j+step]); }}
(3)冒泡排序
冒泡排序的算法比较简单;
算法思想:
比较相邻的两个数,小的往上走,大的往下走,第一次比较之后,将最大放在最下面,一次类推,直至按顺序排好。
代码如下:
void mpSort(int *a,int size) //冒泡排序{ for (int i = 0; i <size; i++)//比较的数 { for (int j = 0; j < size-i-1; j++)//比较的趟数 { if (a[j] > a[j+1]) { int t; t=a[j]; a[j] = a[j+1]; a[j + 1] = t; } } }}
(4)快速排序
对冒泡排序的一种改进方法;
算法思想:
通过一趟排序将待排序的数据分割成独立的两个部分,其中一部分的记录的数据比另一部分记录数据小,
则可分别对这两个部分继续排序,即可达到整个数据有序。
快速排序简单代码如下:
void quick_Sort(int *arr, int h,int r){ if (h < r) { int i = h, j = r, tmp = arr[i]; while (i < j) { while (i < j&&tmp <= arr[j]) //以第一个数为基准,从右到左找小于tmp的数 j--; if (i < j) { arr[i] = arr[j]; i++; } while (i<j&&tmp>arr[i]) //从左到右再找大于tmp的数 i++; if (i < j) { arr[j] = arr[i]; j--; } } arr[i] = tmp; quick_Sort(arr, h, i - 1); //对以第一个数为基准的左边的进行排序 quick_Sort(arr, i + 1, r); //对以第一个数为基准的右边的数进行排序 }}
(5)选择排序
选择排序比较简单。
算法思想:
通过n-i+1(i=1,2…n-1)个记录中选择关键字最小的作为有序序列的第i个记录。
代码如下:
void selectSort(int *a,int size){ for (int i = 0; i < size; i++) { int r = i;//记录下标 for (int j = i+1; j < size; j++) if (a[j] < a[r]) r = j; if (i != r) { int t = a[i]; //交换最小的数和第一个数, a[i] = a[r]; //交换次小的和第二个,依次类推 a[r] = t; } }}
(6)堆排序(Heap Sort)
堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。
堆是改进版的选择结构(树形版),排序过程中可将元素看成一个完全二叉树,每个结点的值都大(小)
于其子节点的值,当每个结点的值都大于子节点的值,称为大顶堆;
当每个结点的值都小于子节点的值,称为小顶堆;
(大顶堆)堆排序算法的思想:
(1)将待排序的数组进行堆的有序化形成一个大顶堆;
(2)将堆顶结点与堆的最后一个结点交换并输出交换后的尾结点;
(3)将剩下的数据重新进行堆的有序化
(4)重复(2)(3)步骤,直至剩下最后一个数据为止。
(小顶堆的排序算法的思想与大顶堆相反)
下面以这组数据为例:
数据 {3,2,1,4,6}
初始堆
3
/ \
2 1
/ \
4 6
(1)调整堆,形成大顶堆
6
/ \
4 1
/ \
2 3
(2)输出最大的值,在从剩余的数中在组成一个大顶堆
4
/ \
3 1
/
2 6
(3)调整堆,使堆顶的值最大,继续输出堆顶,直到剩下最后一个数
3
/ \
2 1
/
4 6
(4)重复(3)
2
/
1 3
4 6
(5)重复(3)
1
2 3
4 6
输出排序后的数据:1 2 3 4 6
堆排序的代码如下所示:
#include <iostream>using namespace std;void adjustHeap(int *a, int i, int size) //调整堆,使其成为大顶堆{ //结点的值大于左结点的值和右结点的值 int lchild = 2 * i + 1; int rchild = 2 * i + 2; if (lchild <size &&a[lchild]>a[i]) { swap(a[lchild], a[i]); } if (rchild<size&&a[rchild]>a[i]) { swap(a[rchild], a[i]); } }void createHeap(int *a, int size) //创建堆{ int i,j; for (int j = 0; j <size / 2; j++) { for (i = size / 2 - 1; i >= 0; i--) { adjustHeap(a, i, size); } } for (int i = 0; i < 8; i++) { cout << " " << a[i]; } cout << endl;}void HeapSort(int *a,int size) //堆排序{ int i; createHeap(a, size); for (i = size - 1; i >0; i--) { swap(a[0],a[i]); //交换堆顶的元素和最后一个结点的值 adjustHeap(a, 0, i);//再次对堆进行调整 }}int main(){ int a[8] = {3,2,1,4,6.7,9,76}; HeapSort(a, 8); for (int i = 0; i < 8; i++) { cout << " " << a[i]; } cout << endl; return 0;}
(7)归并排序
将两个或两个以上的有序表组合成一个新的有序表。
算法思想:
将数组前后相邻的两个有序序列归并为一个有序序列。
归并排序的代码可以去看这篇博客:
http://blog.csdn.net/left_la/article/details/8656953
(8)基数排序
将数据按位拆分,从低到高位逐次比较大小。
eg:以整数为例,将要排序的数先按照个位数的大小,依次放入0-9桶中;
收集,再将数按照十位数的大小,依次放入0-9号桶中;
依次类推,再收集,依次比较高位,依次放入0-9号桶,即可得到结果;
{21,22,44,55,10,3,78,97,66,46}
步骤(1):以个位比较
0:10
1: 21
2:22
3:3
4: 44
5:55
6: 66,46
7:97
8:78
9:
收集:10 21 22 3 44 55 66 46 97 78
步骤(2):以十位比较
0:3
1: 10
2:21,22
3:
4: 44,46
5:55
6: 66
7:78
8:
9:97
收集:3,10,21,22,44,46,55,66,78,97
在数据最高位是2位,排序两次,即可得到正确结果。
#include <iostream>#include <stdlib.h>#include <malloc.h>using namespace std;#define base_size 10 //关键字的基数,此时是十进制的基数#define Size 10int base(int num, int pos){ //得到数对应的高位和低位 int tmp=1; for (int i= 0; i < pos - 1; i++) { tmp *= 10; } return (num / tmp) % 10;}void baseSort(int *arr, int size){ //定义二维数组,即就是待排序数组 int *wat_arr[Size]; for (int i = 0; i <10; i++) { wat_arr[i] = (int *)malloc(sizeof(int)*(size+1)); wat_arr[i][0]=0;//记录每个基准对应的数据个数 } int j, pos; for (pos = 1; pos <= base_size; pos++) { for (j = 0; j < size; j++) { int num = base(arr[j], pos); cout << "num=" << num<<endl; int inde = ++wat_arr[num][0]; wat_arr[num][inde] = arr[j]; } for (int w = 0,j = 0; j < Size; j++) { for (int k = 1; k <= wat_arr[j][0]; k++) arr[w++] = wat_arr[j][k]; wat_arr[j][0] = 0; } }}int GetNumInPos(int num, int pos){ int temp = 1; for (int i = 0; i < pos - 1; i++) temp *= 10; return (num / temp) % 10;}int main(){ int arr[5] = { 19, 12, 39, 45, 57 }; baseSort(arr, 5); for (int i = 0; i < 5; i++) { cout << arr[i] << " "; } return 0;}
对于几种排序的时间复杂度下面这个表做一总结
图片参考来自:数据结构C语言版(严蔚敏版)
部分代码参考到:http://blog.csdn.net/morewindows/article/details/6668714
总结,8种排序算法其实挺重要的,在面试中会经常考到,希望有兴趣的可以好好研究一下。
- 面试常考8种排序算法的总结
- 笔试面试常考排序算法总结
- [面试常考]排序算法总结
- 程序员面试常考,最通俗易懂的排序算法详解
- 面试常考之排序算法
- 面试常考算法题总结(一)
- 面试常考算法题总结(二)
- 笔面试常考数据结构算法总结
- 面试常考排序
- 【Java】几种面试常考排序
- Java实现面试常考的算法
- 常考排序算法
- 面试常考算法题
- 面试常考数据结构算法
- js面试常考算法
- 笔试面试最常涉及到的12种排序算法 总结
- java面试常考的典型例子:冒泡排序
- 面试常考的算法题(@20081031)
- python字符串中取数字
- 区域连通个数问题
- UVA
- vs2013 格式化代码 快捷键
- python 数据结构六 之 字典与集合
- 面试常考8种排序算法的总结
- Ubantu 下TensorFlow环境搭建(CPU版)
- vue计算属性和事件监听
- 如何拷贝复制一个使用svn管理的java web 项目?
- swing 输入框捕获回车事件
- 第五章 构建Spring Web应用程序
- React Web 动画的 5 种创建方式,每一种都不简单
- First Day
- Ransac---重要基础