数据结构-排序-(选择、堆排序、归并排序、基数排序)

目录

一、选择排序

二、堆排序

排序

效率分析

 三、归并排序

 排序

分析

 四、基数排序


一、选择排序

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

 不稳定性

空间复杂度:O(1)

时间复杂度

void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}
void SelectSort(int A[],int n){
    for(int i=0;i<n-1;i++){                //一共进行n-1趟
        int min=i;                         //记录最小元素位置
        for(int j=i+1;j<n;j++)             //在[i...n-1]中选择最小的元素
            if(A[j]<A[min])    mig=j;      //更新最小元素值
        if(min=!=j)    swap(A[i],A[min]);  //封装的swap()函数,交换2个值
    }
}

二、堆排序

 二叉树的顺序存储,大根堆->{根>左右},小根堆->{根<左右}

//建立大根堆
void BuildMaxHeap(int A[],int len){
    for(int i=len/2;i>0;i++)                //从后往前调整所有非终端叶结点
        HeadAdjust(A,i,len);
}
//已k为根的子树调整为大根堆
void HeadAdjust(int A[],int k,int    len){
    A[0]=A[k];                              //A[0]暂存子树的根结点
    for(int i=2*k;i<=len;i*=2){             //沿key较大的子结点向下筛选
        if(i<len&&A[i]<A[i+1])
            i++;                            //取key较大的子结点的下标
        if(A[0]>=A[i])                      //筛选结束
            break;
        else{
            A[k]=A[i];                      //将A[i]调整到双亲结点上
            k=i;                            //修改k值,以便继续向下筛选
        }
    }
    A[k]=A[0];                              //被筛选结点的值放入最终位置
}

排序

获取根第一个,又删除根后恢复大堆根,又取根,一直循环取完为止

//堆排序完成逻辑
void HeapSort(int A[],int len){
    BuildMaxHeap(A,len);        //初建大根堆
    for(int i=len;i>1;i--){     //n-1趟的交换和建堆过程
        swap(A[i],A[1]);        //堆顶元素和堆底元素交换
        HeapAdjust(A,1,i-1)     //把剩余的待排序元素整理成堆
    }
}

效率分析

关键字对比不超过4n,建堆时间O(n),排序时间

时间复杂度:

  不稳定性

空间复杂度:O(1)

时间复杂度

 三、归并排序

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

2个数组值小的放入下方数组,小的和下面数组都后移一位

 二路归并:两个有序序列合二为一     最少对比2-1次

 四路归并:四个有序序列合二为一     最少对比 4-1次

 m路归并:m个有序序列合二为一      最少对比 m-1次

 排序

int *B=(int *)malloc(n*sizeof(int));

//A[low...mid]和A[mid+1...high]各自有序,将两个部分归并
void Merge(int A[],int low,int mid,int high){
    int i,j,k;
    for(k=low;k<=high;k++)
        B[k]=A[k];                            //将A中所有元素复制到B
    for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){
        if(B[i]<=B[j])
            A[k]=B[i++];                      //将较小值复制到A
        else
            A[k]=B[j++];
    }
    while(i<=mid)    A[k++]=B[i++];
    while(j<=high)    A[k++]=B[j++];
}

void MergeSort(int 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);       //归并
    }
}

 

分析

 

   保证稳定性

空间复杂度

时间复杂度

 四、基数排序

数值有个位、十位、百位..等等,第一趟以个位开始进行分配到[0~9]的队列中,结束后收集起来

 后面以十位进行分配收集,百位后收集.....

//基数排序的链式存储
typedef struct LinkNode{
    int data;
    struct LinkNode *next;
}LinkNode,*LinkList;
typedef struct{                //链式队列
    LinkNode *front,*rear;
}LinkQueue;

    保证稳定性

空间复杂度

时间复杂度:​​​​​​​   d:多少趟   r:几个值

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值