数据结构的插入和排序

排序

1 插入排序

1.1 直接插入排序

编程思想:
一:从下标为2的元素开始判断当前元素与前一个元素的大小
二:如果大于则继续循环,小于则进行剩下步骤(三,)
三:将当前元素存入哨兵中(L.r[0]),将前一个元素后移(关键字大的,此处以key为关键字)
四:循环查找插入的位置,循环过程中不断将较大的数据后移。循环结束找到插入位置,插入。

算法代码:

/* 插入排序 */
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];                       //(1)
            L.r[i]=L.r[i-1];
            for(j=i-2;L.r[0].key<L.r[j].key;j--) //(2)
                L.r[j+1]=L.r[j];                 
            L.r[j+1]=L.r[0];                     
        }
    }
}

解释:
(1):因为以key作为关键字,当L.r[i].key<L.r[i-1].key,整个都跟着变化即L.r[0]=L.r[i]
(2):j=i-2,说明从后面开始查找,i-2是因为i-1为空的存储位(存储后移的数据或L.r[0]),i为原较大值

1.2 折半插入排序

编程思想:
一:从i=2开始循环直到L.Length
二:将L.r[i]存入哨兵中
三:low=1;high=i-1(i-1是因为将i插入到前面已排好的序列中)
四:进行循环直到low大于high
五:中间位置m=(low+high)/2
六:判断大小,如果暂存在哨兵中的数据小于中点数据则high=m-1,如果大于则low=m+1;
七:j=i-1,从后面开始循环并将记录后移直到j=high
八:循环结束将哨兵值插入

算法代码:

/* 折半插入排序 */
void BInsertSort(SqList &L){
    int i,j,low,high,m;
    for(i=2;i<=L.Length;i++){                          //(1)
        L.r[0]=L.r[i];
        low=1;
        high=i-1;                                      //(2)
        while(low<=high){
            m=(low+high)/2;
            if(L.r[0].key<L.r[m].key) high=m-1;
            else low=m+1;
        }
        for(j=i-1;j>=high+1;j--) L.r[j+1]=L.r[j];      //(3)
        L.r[high+1]=L.r[0];                            //(4)
    }
}

解释:
(1):从i=2是因为i=1已经为一个有序队列了
(2):插入队列范围为第一个元素到目标元素前一个元素
(3):确定位置完有两种情况1:high<m=low 2:high=m<low,我们想将哨兵中的数值插入到high+1的位置以满足两种情况,所以循环结束是完成high+1的后移,使high+1空出来
(4):high+1空出来了

1.3 哈希排序

编程思想:
一:进行循环i=dk+1;i<=Length;i++
二:判断L.r[i]与l.r[i-dk]的大小,如果前者小于后者则将较小值放入哨兵之中
三:在1+dk
n(n=0,1,2,3·····)中,将较大记录后移找到插入的位置
四:哨兵插入
*

算法代码:

/* 希尔排序 */
/* 希尔排序 */
void ShellInsert(SqList &L,int dk){
    int i,j;
    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];
                /* OutPut(L) */

            }
            L.r[j+dk]=L.r[0];
        }
    }
    /* OutPut(L); */
}

void ShellSort(SqList &L,int dt[],int t){
    int k;
    for(k=0;k<t;k++){
        ShellInsert(L,dt[k]);
    }
}

/* 创建间隔数组 */
void CreateIntervalArray(int *dt,int num){
    int i;
    for(i=0;i<num;i++){
        cin>>dt[i];
    }
}

2 交换排序

2.1 冒泡排序

编程思想:
一:循环直到m<=0(m=Length-1)
二:循环判断大小,前面的比后面的大则交换(将最大的沉底)
三:m–

算法代码:

void BubbleSort(SqList &L){
    int m,flag,j;
    RedType t;
    m=L.Length-1;
    flag=1;                                //(1)
    while((m>0)&&(flag==1)){               //(2)
        flag=0;
        for(j=1;j<=m;j++){                 //(3)
            if(L.r[j].key>L.r[j+1].key){
                flag=1;
                t=L.r[j];
                L.r[j]=L.r[j+1];
                L.r[j+1]=t;
            }
        }
        m--;
    }
}

解释:
(1):flag为优化算法,发现排好序后可以立马结束
(2):循环Length-1次
(3):循环Length-1次

3 选择排序

3.1 简单选择排序

编程思想:
一:进行循环只用循环Length-1次,最后一个不用排
二:k=i,循环j=i+1;j<=Length寻找最小关键字
三:用k来保存找到的最小关键字的记录
四:如果k!=i则进行交换

算法代码:

/* 简单选择排序 */
void SelectSort(SqList &L){
    int k,i,j;
    RedType t;
    for(i=1;i<L.Length;i++){
        k=i;
        for(j=i+1;j<=L.Length;j++){
            if(L.r[k].key>=L.r[j].key) k=j;
        }
        if(k!=i)                             //(1)
        {
            t=L.r[i];L.r[i]=L.r[k];L.r[k]=t;
        }
    }
}

解释:
(1):表示查到更小的关键字记录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值