数据结构期末复习Ⅷ——排序

插入排序(打牌时理牌的过程)

简单插入排序(带哨兵)
void InsertSort(SqList &L){
    int i,j;//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];//复制为哨兵
            for(j = i - 1; L.r[0].key < L.r[j].key; j--){
                L.r[j+1] = L.r[j];
            }
            L.r[j+1] = L.r[0];
        }
    }
}//稳定
折半插入排序
void BInsetSort(SqList &L){
    for(i = 2; i <= L.length; i++){
        L.r[0] = L.r[i];
        low = 1, high = i - 1;
        while(low <= high){
            mid = (low + high) / 2;
            if(L.r[0].key < L.r[mid].key) high = mid - 1;
            else low = mid + 1;
        }
        for(j = i - 1; j >= high + 1; j--) L.r[j+1] = L.r[j];//往后移
        L.r[high + 1] = L.r[0];
    }
}//稳定
增加步长——希尔排序
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];//暂存,并不作为哨兵,因为虽说是顺序遍历,但并不会真正到L.r[0]处
            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];//归位
        }
    }
}
void ShellSort(SqList &L, int dt[], int t){
    for(k = 0; k < t; k++) ShellInsert(L, dt[k]);//dt数组最后一次取增量一定是1, 然后数组元素之间互质
}//不稳定

交换排序(交换元素的过程)

冒泡排序
void BubbleSort(SqList &L){
    bool flag = 1;
    for(i = 1; i <= L.length-1 && flag; i++){//总共需比较n-1次
        flag = 0;
        for(j = 1; j <= L.length - i; j++){
            flag = 1;//发生了交换,下次继续;如果没有,之后的交换就没有必要
            if(L.r[j].key > L.r[j+1].key) swap(L.r[j],L.r[j+1]);
        }
    }
}//稳定
快速排序
//内部排序中最快的一种;越乱越好(非自然排序),有序情况下退化为冒泡;不稳定
int Partition(SqList &L, int low, int high){
    L.r[0] = L.r[low];
    pivotkey = L.r[low].ley;
    while(low < high){
        while(low < high && pivotkey <= L.r[high].key) high--;
        L.r[low] = L.r[high];
        while(low < high && pivotkey >= L.r[low].key) low++;
        L.r[high] = L.r[low];
    }
    L.r[low] = L.r[0];
    return low;
}
void QSort(SqList &L, int low, int high){
    if(low < high){
        pivotloc = Partition(L, low, high);
        QSort(L, low, pivotloc - 1);
        QSort(L, pivotloc + 1, high);
    }
}

选择排序(选择最小的过程)

简单选择排序
void SelectSort(SqList &L){
    for(i = 1; i < L.length; i++){
        k = i;
        for(j = i + 1; j <= L.length; j++){
            if(L.r[j].key < L.r[k].key) k = j;//k记录最小值下标
        }
        if(k != i) swap(L.r[k], L.r[i]);//如果i元素不是最小值,则换
    }
}//不稳定
堆排序

最初态就是将序列从上到下从左到右放入完全二叉树,然后建堆,建堆的过程就是从元素n/2到1调整堆的过程,最后不断输出堆顶,将堆顶与最后一个元素交换,然后调整。

归并排序

二路归并,要求的空间最多,分到分无可分然后merge,merge的过程就是申请空间+双指针

基数排序(又叫桶排)

多关键字,分配与收集,适用于“先按数学成绩排序,然后按总分排序(要求数学好的在前面”这种情况,不稳定。

稳定性总结

不稳定稳定
插入排序中的希尔排序,交换排序中的快排,两个选择排序其他

好消息

终于学完啦!而且这一章手写算法的可能性不大,各位小可爱只需熟悉各个算法的性质、用法、稳定性即可。

错题

  1. 堆排序是一种选择排序。选择最大/小值
  2. 希尔排序增量为3时,序列1~10的第一组应该为1,4,7,10。增量为1时,直接插入排序。
  3. 只要区间长度超过1就要执行快排。
  4. 若要求在最坏情况下也能尽快地对序列进行稳定的排序——归并
  5. 堆排序如何写关键码状态?首先:建好堆的序列,然后依次输出堆顶,注意每次输出堆顶之后的序列必须保持大/小顶堆性质。

数据结构完结撒花!★,°:.☆( ̄▽ ̄)/$:.°★

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值