关于七大排序问题《一》

来源:互联网 发布:淘宝 跑腿 编辑:程序博客网 时间:2024/06/13 21:26

常见的排序如图所示:


首先依次来分析各个排序:

1,直接插入排序:

插入排序一般应用于有序或接近于有序的数列区间。它的时间复杂度是O(N)。

插入思想:如如所示,


那我们现在实现这个代码:

#include<iostream>#include<assert.h>void Insertsort(int*a, size_t n){assert(a);for (size_t i = 0; i < n - 1; i++){int end=a[0];int tmp = a[end + 1];//tmp表示插入这个数的值while (end>0){if (a[end] > tmp){a[tmp + 1] = a[end];--end;}else{break;}}a[end + 1] = tmp;}}void test(){int a[] = { 2, 5, 4, 9, 3, 6, 8, 7,1, 0 };Insertsort(a, sizeof(a) / sizeof(a[0]));}int main(){test();return 0;}
2,希尔排序

希尔排序是上插入排序的一种优化,它的思想是:


实现希尔排序的程序:

void shellsort(int* a, size_t n){assert(a);int gap = 3;for (size_t i = 0; i < n - gap; ++i)//这里不是9,6,3排好之后再排8,5,2,最后排7,4,1{//因为这里是++i,将9和6交换之后,++i,8和5交换,再++i,7和4交换int end = i;                    //以此类推int tmp = a[end + gap];while (end >= 0){if (a[end] < tmp){break;}else{a[end + gap] = a[end];end -= gap;}}a[end + gap] = tmp;}}
如果将上面的gap=3改为=1那就是插入排序,所以当gap越大时就越不接近有序。

3,选择排序:a,选择排序:(以升序为例)

它的思想如图所示:


它实现的程序为:

void Selectsort(int* a, size_t n){assert(a);size_t left = 0;size_t right = n - 1;while (left < right){size_t min = left;size_t max = right;for (size_t i = left; i <= right; ++i){if (a[min]>a[i]){min = i;}if (a[max] < a[i]){max = i;}swap(a[min], a[left]);if (max == left){max = min;}swap(a[max], a[right]);++left;++right;}}}
4,堆排序:

对是一颗顺序存储的完全二叉树,我们以大堆为例进行说明。

首先我们将数组调整为堆,以图为例说明:


实现堆排序的代码为:

void AdjustDown(int* a, size_t root, size_t n){size_t parent = root;size_t child = parent * 2 + 1;while (child < n){if (child + 1 < n&&a[child + 1] > a[child]){++child;}if (a[child]>a[parent]){swap(a[child], a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void HeapSort(int* a, size_t n){assert(a);for (int i = (n - 2) / 2; i >= 0; --i){AdjustDown(a, i, n);}size_t end = n - 1;while (end > 0){swap(a[0], a[end]);AdjustDown(a, 0, end);}}