插入类
直接插入排序
步骤如下:
待排序的记录存放在数组r[1…n],r[1]是一个有序序列,在r[0]出设置监视哨。
(1)确定插入位置: 循环n-1次,使用顺序查找法,查找r[i](i = 2,…,n)在已排好序的序列r[1,…i-1]中得插入位置;
(2)插入元素: 将r[i[ 插入到表长为i-1的有序序列r[1,…i-1]中,直到插入r[n],得到一个表长为n的有序序列。
代码如下:
直接插入排序
void InsertSort(SqList &L)
{
for(int i = 2;i <= L.length;i++){
if(L.r[i].key < L.r[i-1].key){
L.r[0] = L.r[i]; //r[0]作为监视哨,临时保存r[i]的值;
L.r[i] = L.r[i-1];
for(int j = i-2;L.r[0].key < L.r[j].key; --j){
L.r[j+1] = L.r[j]; //找到r[i]或者说此时r[0]中关键字需要插入的位置为j之后j+1处
}
L.r[j+1] = L.r[0];
} //if
} // for
}
算法特点:
(1)稳定排序;
(2)适用于顺序存储结构与链式存储结构,在单链表上无需移动记录,只需修改相应的指针;
(3)适用于初始记录基本有序(正序)的情况。当初始记录无序,n较大,不宜使用。
(4)时间复杂度:O(n²); 空间复杂度: O(1).
希尔排序
算法如下:
将整个待排序记录序列中相隔某个“增量”的记录分成一组,进行直接插入排序,而后逐次增加每组的数据量(即减小“增量”),经过几次分组排序后,整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
代码如下:
希尔插入排序
//对顺序表L做一趟增量是dk的希尔插入排序
void ShellInsert(SqList &L,int dk)
{
for(i = dk+1;i <= L.length; ++i){
if(L.r[i].key < L.r[i-dk].key){
L.r[0] = L.r[i];
for(j = i-dk;j>0 && L.r[0].key < L.r[j].key;j-=dk){
L.r[j+dk] = L.r[j];
}
L.r[j+dk] = L.r[0];
}//if
} //for
}
//按增量序列dt[0..t-1]对顺序表L作t趟希尔排序
void ShellSort(SqList &L,int dt[],int t){
for(k = 0;k < t;++k)
ShellInsert(L,dt[k]);
}
算法特点:
(1)不稳定排序;
(2)只能用于顺序结构;
(3)增量序列中的值没有除1以外的公因子,且最后一个增量值必须为1;
(4)适合初始记录无序、n较大时的情况
(5)时间复杂度: O(n1.3) 【平均情况下】空间复杂度: O(1).
交换类
冒泡排序
步骤如下:
(1)首先将比较第一、二个记录的关键字,若为逆序,则互换;然后比较