对于非比较排序算法,如计数排序、基数排序,你们若是感兴趣,能够查看博客http://10740184.blog.51cto.com/10730184/1782077。本文,我将介绍比较排序算法。
算法
直接插入排序:数组
在序列中,假设升序排序ide
1)从0处开始。优化
1)若走到begin =3处,将begin处元素保存给tmp,比较tmp处的元素与begin--处元素大小关系,若begin处<begin-1处,将begin-1处元素移动到begin;若大于,则不变化。再用tmp去和begin--处的元素用一样的方法去做比较,直至begin此时减小到数组起始坐标0以前结束。ui
3)以此类推,依次走完序列。spa
时间复杂度:O()
设计
代码以下:blog
//Sequence in ascending order void InsertSort(int* a,int size) { assert(a); for (int begin = 0; begin < size ; begin++) { int tmp = a[begin]; int end = begin-1; while (end >= 0 && tmp < a[end]) { a[end+1] = a[end]; a[end] = tmp; end--; } } }
2.希尔排序排序
希尔排序其实是直接插入排序的优化和变形。假设升序排序递归
1)咱们先去取一个增量值gap,将序列分为几组。
2)而后咱们分组去排序。当每一个分组排序排好后,至关于整个序列的顺序就排列好了。
3)比较a[i],a[i+gap]大小关系,若a[i]>a[i+gap],则交换。不然不处理。日后走,继续该步骤……
代码以下:
//Sequence in ascending order void ShellSort(int* a, int size) { assert(a); int gap = size; while (gap > 1) { gap = gap / 3 + 1; for (int i = 0; i < size - gap; i++) { int end = i; int tmp = a[end + gap]; while (end >= 0 && a[end] > a[end + gap]) { a[end+gap] = a[end]; a[end] = tmp; end -= gap; } } } }
3.选择排序
假设升序排序
1)第1次遍历整个数组,找出最小(大)的元素,将这个元素放于序列为0(size-1)处。此时,未排序的序列不包括0(size-1)处.第2次,一样的方法找到找到剩下的未排序的序列中的最小的元素,放于序列为1处。
2)重复,直至排到序列结尾处,这个序列就排序好了。
时间复杂度:O(N^2)。
代码以下:
//Sequence in ascending order void SelectSort(int* a, int size) { assert(a); for (int i = 0; i < size; i++) { int minnum = i; for (int j = i+1; j < size;j++) { if (a[minnum] > a[j]) { minnum = j; } } if (i != minnum) { swap(a[i], a[minnum]); } } }
4.堆排序
假设升序排序
咱们先要思考升序序列,咱们须要建一个最大堆仍是最小堆?
若是最小堆,那么每一个根节点的元素大于它的子女节点的元素。可是,此时却不能保证她的左右节点必定哪一个大于哪个,且不能保证不一样一层的左右子树的节点元素大小。
因此,要设计升序排序,咱们须要建一个最大堆。
1)建一个最大堆。
2)第1次,将根节点的元素与堆的最后一个节点元素交换,这样确定保证最大元素在堆的最后一个节点处,而后此时的根节点并不必定知足大于左右子女节点,所以将其向下调整,至合适位置处。第2次,将根节点的元素与堆的倒数第2个节点元素交换,向下调整交换后的根节点至合适位置……
代码以下:
void _AdjustDown(int parent, int* a, int size) { int child = 2 * parent + 1; while (child < size) { if (child + 1 < size && a[child + 1] > a[child]) { child++; } if (a[child] >a[parent]) { swap(a[child], a[parent]); parent = child; child = 2 * parent + 1; } else { break; } } } //Sequence in ascending order void HeapSort(int* a, int size) { assert(a); for (int i = (size - 2) / 2; i >= 0;i--) { _AdjustDown(i, a, size); } for (int i = 0; i < size -1; i++) { swap(a[0], a[size - i -1]); _AdjustDown(0, a, size-i-1); } }
5.冒泡排序
假设升序排序
冒泡,顾名思义,像泡同样慢慢地沉。
1)第一次,比较a[0],a[1]大小,若a[0]>a[1],则交换它们。再比较a[1],a[2],若a[1]>a[2],则交换……这样一直到比较a[size-1],a[size]结束,此时已经将一个最大的元素沉到序列的最尾端size-1处了。
2)第二次,重复上述操做,可将次最大的元素沉到size-2处。
3)重复,完成排序。
比较:
冒泡排序是两两比较,每次将最大的元素日后沉。而选择排序不一样的是,每次遍历选择出最大元素放到最后。
代码以下:
//Sequence in ascending order void BubbleSort(int* a, int size) { assert(a); for (int i = 0; i < size; i++) { for (int j = 0; j < size - i -1; j++) { if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); } } } }
6.快速排序
快速排序,顾名思义,排序算法很快,它是最快的排序。时间复杂度为:O(n*lgn).适合于比较乱的 序列。假设升序排序
这两种方法都挺简单的,相比而言,方法2代码更短,更加简单!!!你们本身斟酌使用!!!
方法1:
咱们这里先介绍快速排序的挖坑法。(每次数据被挪走后都至关于挖出了一个坑,这个坑能够把其余数据挪过来放。)
对于序列:{ 5, 1,8,12, 19, 3, 7, 2, 4 ,11}
1)咱们取序列的第一个数据当作比较的基准,而且设定序号为0的位置为低位置low,序号为size-1的位置为高位置high。
2)取出序列的基准元素key,此刻的5.
在high位置从右往左找直到找到比基准值5小的元素,即此刻的元素4处中止。
而后,在low位置从左往右找直到找到比基准值5大的元素,即此刻的元素8中止。
因为此时的基准元素key被取出,存放它的位置就空下来了。将找到的元素4赋值给此刻的这个位置.
3)此时元素4存放的位置空下来了,将找到的低位置的8放到这个位置去。
4)重复这样的动做,2放到基准位置,12放到原来2的位置……
5)直到low>=high时中止。
以上是一次快速排序,在通过一次快速排序后,high与low相遇左右各造成有序序列。再将这个相遇位置左右各当成一个序列,继续进行快速排序,最终能够将序列排序好。
代码以下:
void QuickSort(int* a, int left,int right) { assert(a); int low = left; int high = right; int key = a[low]; while (low < high) { while (low < high && key <= a[high]) { high--; } a[low] = a[high]; while (low <high && key >= a[low]) { low++; } a[high] = a[low]; } a[low] = key; if (left <= high) { QuickSort(a, left, low - 1); QuickSort(a, low + 1, right); } }
方法2:
快速排序的prev、cur法:
为了方便给你们分享,我把它称之为prev、cur法。
1)引入两个位置,prev、cur,cur首先指向序列的初始位置,prev指向cur的前面(即:若cur=0,则prev=-1位置处)。
2)咱们将基准key取成序列的最后一个位置right处的元素。
3)cur从初始位置处开始,(由于要排成升序),找一个cur处的值大于key的值中止,不然小于key的值的话,就一直继续cur往前走,此时prev是不动的。可是当找到cur处的值大于key的值时,++prev,再将prev处的值与cur的值进行交换。(注意,prev前置加加,即prev先日后走一步再交换值)。
4)cur继续往前走,继续重复第3)条步骤,直到遇到right-cur=1,立刻就要相交时中止。
5)中止后,递归左右区间,重复上述步骤,直至区间只剩下一个元素时无需继续划分区间递归,排序结束。
代码以下:
int QuickSort(int* a, int left, int right) { assert(a); int cur = left; int prev = cur - 1; int key = mid(a,left,right); swap(key, a[right]); while (cur < right) { if (a[cur] <= a[right]) { swap(a[++prev], a[cur]); } cur++; } swap(a[++prev], a[right]); if (prev - 1 > left) { QuickSort(a, left, prev - 1); } if (prev + 1 < right) { QuickSort(a, prev + 1, right); } }