嗯!我向考试屈服了,采用倒叙复习法,哭~
排序算法
- 内排序:待排序序列完全放在内存中
- 外排序:排序过程中需要访问外存储器
插入排序
将待排序的数据插入到已排序的数据序列中
直接插入排序(稳定)
先假定第一个元素已经排好顺序,将后面的元素依次插入已经排好的序列中。
void insertSort(SqList&L){
int i,j;
for(i=2;i<L.length;i++){
if(L.r[i].key<L.r[i-1].key){
L.r[0]=L.r[i];
L.r[i]=L.r[i-1];
for(j=i-2;L.r[j].key>L.r[0].key;j--)//查找插入位置
L.r[j+1]=L.r[j];
L.r[j+1]=L.r[0];
}
}
}
二分插入排序(稳定)
与直接插入相比,在插入第i个数据时,用二分法查找待插入位置。减少比较的次数。
希尔排序(缩小增量法)
一个d值排序完为一趟。
交换排序
两两比较,不满足顺序要求则进行交换。
冒泡排序(稳定)
每一趟从头到尾进行两两比较排序直至某一趟没有发生任何数据元素的交换或做完n-1趟。
void qppx(SqList&L){
int i,j,k;
j=0;
k=1;
while(j<L.length && k>0){
k=0;
for(i=0;i<L.length;i++){
if(L.r[i].key<L.r[i-1].key){
L.r[0].key=L.r[i].key;
L.r[i].key=L.r[i-1].key;
L.r[i].key=L.r[0].key;
k++;
}
}
j++;
}
}
快速排序(不稳定)
一趟快速排序,将待排序序列划分为大小两个子序列。
重复一趟快排直至每部分只有一个数据元素。
一个不断挖坑、填坑的过程
- 遇到与基准相同的数据元素,放在基准的右侧
- 基准可以选取第一个数据元素、最后一个数据元素、中间位置的数据元素
当待排序元素有序(正序/逆序)时,为排序的最坏情况。
选择排序
每次从待排序的数据元素中选取关键字最小的数据元素,顺序放在已排序的数据元素的最后,直到全部排完。
简单(直接)选择排序
每一趟选取最小的数据元素,放在排序完成后应该放置的位置上。
堆排序(不稳定)
小顶堆:非叶结点值不大于左右孩子
大顶堆:非叶结点值不小于左右孩子
堆排序方法:将待排序的数据建为大顶堆,取最大的数据,重建堆,重复操作,直至数据排好序。
归并排序
将待排序序列划分为若干有序子序列,将有序子序列合并
注意:趟数是从分裂后的合并开始算起,可能会考第n次归并后的序列。
基数排序
根据关键字本身的性质进行排序。
关键字可以有多个,分为最主位关键字和最次位关键字。(类似大小和花色)
低位优先基数排序
总结
方法 | 稳定性 | 平均性能分析(好) | 空间复杂度(差) |
---|---|---|---|
直接插入排序 | 稳定 | ||
二分插入排序 | 稳定 | ||
希尔排序 | 不稳定 | ||
冒泡排序 | 稳定 | ||
快速排序 | 不稳定 | O(nlgn) | |
简单选择排序 | 不稳定 | ||
堆排序 | 不稳定 | O(nlgn) | |
归并排序 | 稳定 | O(nlgn) | O(n) |
基数排序 | 稳定 |