内部排序算法
直接插入排序(从原位置在有序部分逐次比较找到最终位置插入)
void InsertSort(ElemType A[], int n) { int i, j; for( i = 2, i <= n; i++) if(A[i].key < A[i - 1].key) { A[0] = A[i]; for(j = i - 1; A[0].key < A[i].key; --j) A[j + 1] = A[j]; A[j + 1] = A[0]; } }
折半插入排序
void InsertSort(ElemType A[], int n) { int i, j, low, high, mid; for(i = 2; i <= n; i++) { A[0] = A[i]; low = 1; high = i - 1; while(low <= high) { mid = (low + high) / 2; if(A[mid].key > A[0].key) high = mid - 1; else low = mid + 1; } for(j = i - 1; j >= high + 1; --j) A[j + 1]= A[j]; A[high + 1] = A[0]; } }
希尔排序
void ShellSort(ElemType A[], int n) { for(dk = len / 2; dk >= 1; dk = dk / 2) for(i = dk + 1; i <= n; ++i) if(A[i].key < A[i - dk].key) { A[0] = A[i]; for(j = i - dk; j > 0 && A[0].key < A[j].key; j -= dk) A[j + dk] = A[j]; A[j + dk] = A[0]; } }
冒泡排序
void BubbleSort(ElemType A[], int n){ for(i = 0; i < n - 1; i++) { flag = false; for(j = n - 1; j > i; j--) if(A[j - 1].key > A[j].key) { swap(A[j - 1], A[j]); flag = true; } if(flag == false) return; } }
快速排序
int Partition(ElemType A[], int low, int high) { ElemType pivot = A[low]; while(low < high) { while(low < high && A[high] >= pivot) --high; A[low] = A[high]; while(low < high && A[low] <= pivot) ++low; A[high] = A[low]; } A[low] = pivot; return low; }
快速排序的运行时间与划分是否对称有关,而后者又与具体使用的划分算法有关。
且快速排序与冒泡排序都能在每一趟排序将一个元素放在它的最终位置上。
简单选择排序
void SelectSort(ElemType A[], int n) { for(i = 0; i < n - 1; i++) { min = i; for(j = i + 1; j < n; j++) if(A[j] < A[min]) min = j; } }
堆排序
void AdjustDown(ElemType A[], int k, int len) { A[0] = A[K]; for(i = 2 * k; i <= len; i *= 2) { if(i < len && A[i] < A[i + 1]) i++; if(A[0] >= A[i]) break; else { A[k] = A[i]; k = i; } } A[k] = A[0]; } void BuildMaxHeap(ElemType A[], int len) { for(int i = len / 2; i > 0; i--) AdjustDown(A, i ,len); }
向上调整堆
void AdjustUp(ElemType A[], int k) { A[0] = A[k]; int i = k / 2; while(i > 0 && A[i] < A[0]) { A[k] = A[i]; k = i; i = k / 2; } A[k] = A[0]; }
归并排序
ElemType *B = (ElemType *)malloc((n + 1)*sizeof(ElemType)); void Merge(ElemType A[], int low, int mid, int high) { for(int k = low; k <= high; k++) B[k] = A[k]; for(i = low, j= mid +1, k = i; i <= mid && j<= high; k++) { if(B[i] <= B[j]) A[k] = B[i++]; else A[k] = B[j++]' } while(i < mid) A[k++] = B[i++]; while(j <= high) A[k++] = B[J++]; } void MergeSort(ElemType A[], int low, int high) { if(low < high) { int mid = (low + high) / 2; MergeSort(A, low, mid); MergeSort(A. mid + 1, hgih); Merge(A, low ,mid, high); } }
效率比较
表格中的时间效率是在平均情况下的考虑
| 空间效率 | 时间效率 | 稳定性 | 比较次数 | 比较相关性 | |
| 直接插入排序 | O(1) | O(n2) | 稳定 | 比较次数取决于初始序列 | |
| 折半插入排序 | O(1) | O(n2) 优于直接插排 | 稳定 | O(nlog2n) | 比较次数仅取决于元素个数 |
| 希尔排序 | O(1) | O(n2) | 不稳定 | ||
| 冒泡排序 | O(1) | O(n2) | 稳定 | n(n-1)/2 | |
| 快速排序 | O(log2n) | O(nlog2n) |
不稳定 |
||
| 简单选择排序 | O(1) | O(n2) | 不稳定 | n(n-1)/2 | 比较次数与初始序列无关 |
| 堆排序 | O(1) | O(nlog2n) | 不稳定 | 比较次数与初始序列无关 | |
| 归并排序 | O(n) | O(nlog2n) | 稳定 | 比较次数的数量级与初始序列无关 |
快速排序被认为是目前基于比较的内部排序中最好的排序方法。而希尔排序算法仅适用于当线性表为顺序存储时。
当文件的n个关键字随机分布时,任何借助于“比较”的排序算法,至少需要O(nlog2n)的时间。
当记录本身信息量较大时,为避免耗费大量时间移动记录,可用链表作为存储结构。
-----------------------------------------------------------------------------------------------
当你不断地追求卓越的时候,成功就会不期而至。

浙公网安备 33010602011771号