常见排序算法的实现
插入排序:简单地说,就是就将无序序列依次插入到有序序列中。
算法描述:
1. 从第一个元素开始,该元素可以认为已经被排序
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5. 将新元素插入到该位置后
6. 重复步骤2~5
时间复杂度:
最坏情况;O(n^2);
平 均:O(n^2);
/*********** 构建大顶堆 ************/void AdjustTop(int *p, const int len){ assert(p != NULL); int pos = len / 2 - 1; int t; int temp; while (pos >= 0) { if (pos*2+2 == len) // 只有自由左子树的情况 { t = p[pos*2+1] > p[pos] ? pos*2+1 : pos; } else// 左右子树都存在 { t = p[pos*2+1] > p[pos*2+2] ? pos*2+1 : pos*2+2; t = p[t] > p[pos] ? t : pos; } if (t != pos)// 加此条件判断以减少交换次数 { temp = p[pos]; p[pos] = p[t]; p[t] = temp; } pos--; }}/*********** 堆排序 ************/void HeapSort(int *p, const int len){ assert(p != NULL); int i; int temp; for (i = 0; i < len; i++) { AdjustTop(p, len-i);//对剩余元素重新构建“大顶堆” temp = p[0]; p[0] = p[len-i-1]; p[len-i-1] = temp; }}
各种内部排序方法的比较:
1. 就平均时间性能而言,快速排序最佳,其所需时间最少,但快速排序在最坏情况下的性能不如堆排序;
2. 由于堆排序在最坏情况下的时间复杂度和平均时间复杂度差不多,所以待排序列中元素初始时的顺序对该排序算法没有太大影响。
2. 从方法的稳定性来看,所有时间复杂度为O(n^2)的简单排序法都是稳定的(包括插入排序、冒泡排序、选择排序)。一般来说,排序过程中的“比较”是在“相邻的两个记录关键字”间进行的排序方法都是稳定的。