排序(中)

选择排序

思想:每一趟在待排序元素中选取关键字最小或最大的元素加入有序子序列

简单选择排序

选择最小的,n个元素需要处理n-1躺

void SelectSort(int A[],int n){
    for(int i =0 ;i<n-1;i++){
       int min = i                  //记录最小的值
        for(int j=i+1;j<n;j++)      //在[i,n-1]中找到最小的值
            if(A[j]<A[min]) min=j;  
        if(min!=i)  swap(A[j],A[min]);
    }
}
void swap(int &a,int &b){
     int temp =a;
     a=b;
     b=temp;
}
  • 空间复杂度:O(1) 时间复杂度:O(n平方) 不稳定

堆排序

大根堆:完全二叉树中,根>=左右

小根堆:完全二叉树中,根<=左右

如何由一个无序序列建成一个堆?

如何在输出堆顶元素后,调整剩余元素为一个新的堆?

//建立大根堆
void BuildMaxHeap(int A[],int len){
    //找到最后一个非叶子节点进行处理
    for(int i=len/2;i>0;i--){      //len/2找到最后一个非叶子节点
        HeadJust(A,i,len);  //调整成大根堆
    }
}

void HeadJust(int A[],int i,int len){
    A[0]=A[i];
    for(int k=2*i;k<=len&&;k=k*2){          //比较A[i]的孩子做交换,可能有很多层孩子
        if(k<len&&A[k]<A[k+1]) k++;         //对比当前处理的根节点的左右孩子谁大,i<len保证i节点是有右兄弟的
        if(A[k]<=A[0]){                     //证明根节点比较大,不用交换
            break;
        }else{
            A[i]=A[k];                     //根节点小,交换
            i=k;
        }
    }
    A[i]=A[0];
}
​
void HeapSort(int A[],int len){
    BulidMaxHeap(A,len);
    for(int i =len;i>0;i++){             //n-1趟的交换和建堆的过程
        A[i]=A[1];                       //交换堆顶与堆底
        HeadJust(A,1,i-1);               //把剩余的待排序元素整理成堆
    }
}
​
  • 空间复杂度:O(n平方) 时间复杂度:最好:O(nlogn) 最坏:O(nlogn) 平均:O(nlogn) 不稳定

归并排序

把两个或多个已经有序的序列合并成一个

核心:把数组内的两个有序序列归并为一个

Elemtype *B=(ElemType*) malloc((n+1)*sizeof(ElemType));
​
void Merge(ElemType A[],int low,int mid,int high){
    int k;
    //两段必须各自有序
    for(int i=low;i<=high;i++){
        A[i]=B[i];   //将A拷贝到B
    }
    for(i=low,j=mid+1;k=low;i<=mid&&j<=high;k++){     //比较两段的大小
        if(B[i]>B[j]) A[k]=B[j++];   //前面一半第一个大于后面一半的第一个,修改A[]的值为小的,并且后面一半的指针后移一位
        else if(B[i]<=B[j]) A[k]=B[i++];  //前<后,修改A[]的值为小的,且前一半的指针后移一个
    }
    while(j<=high) A[k++]=B[j++];     //如果后半段还没遍历完,就把剩下的全加到A里面去
    while(i<=mid)  A[k++]=B[i++];     //前
}
​
void MergeSort(ElemType A[],int low,int high){
    if(low<high){
        int mid =(low + high)/2;   //从中间划分
        MergeSort(A,low,mid);      //对左边
        MergeSort(A,mid+1,high);   //对右边
        Merge(A,low,mid,high);     //归并
    }
}
                        [8, 3, 1, 7, 0, 4, 9, 2, 6, 5]
                           |                     |
                      [8, 3, 1, 7, 0] | [4, 9, 2, 6, 5]     |       Divide Phase
                         /       |        \          |
                   [8, 3] | [1, 7, 0] | [4, 9] | [2, 6, 5] |
                  /    |         |          |          |
               [8] | [3] | [1, 7]  [0] | [4] [9]  |   [2] [5,6]     Divide Phase
                  \ /         \     /       |         |     /   |
                 [8, 3]        [0, 1, 7]   [4, 9]  [2, 5, 6]        Merge Phase
                    \_______|_________/           \_______/
                            |                         |
                    [0, 1, 3, 7, 8]            [2, 4, 5, 6, 9]      Merge Phase
                           \__________________________/
                                          |
                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]   Merge Phase
  • 空间复杂度:O(n) 时间复杂度:最好:O(nlogn) 最坏:O(nlogn) 平均:O(nlogn) 稳定

基数排序(桶、箱排序)

基本思想:分配+收集

假设有以下未排序的整数数组:[170, 45, 75, 90, 802, 24, 2, 66]
​
第一次迭代(按照个位)
桶0:170, 90
桶1:
桶2:802,2
桶3:
桶4:24
桶5:45, 75
桶6:66
桶7:
桶8:
桶9:
得到数组:[170, 90, 802, 2, 24, 45, 75, 66]
​
第二次迭代(按十位)
桶0:802,002, 024
桶1:
桶2:
桶3:
桶4:045, 066
桶5:075
桶6:
桶7:
桶8:090
桶9:170
得到数组:[802, 002, 024, 045, 066, 170, 075, 090]
​
第三次迭代:
桶0:002, 024, 045, 066, 075, 090
桶1:170
桶2:
桶3:
桶4:
桶5:
桶6:
桶7:
桶8:
桶9:802
得到数组:[002, 024, 045, 066, 075, 090, 170, 802]
  • 最好情况 O(n+m) 最坏情况O(k(n+m)) 平均情况 O(k(n+m)) 空间复杂度O(n+m) 稳定

k:关键字的个数(分配多少趟) m:桶的个数(多少个桶就要收集多少次) n是元素的个数(要扔多少个)

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值