• 软考--数据结构(排序算法)


     

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    /*
    直接插入排序:
    枚举一个元素分别与前面的元素比较,直到遇到比自己更小的
    时间复杂度O(n2),空间复杂度O(1),稳定
    */
    void insertSort(int *a,int len){
            for(int i=1;i<len;i++){
                    if(a[i]<a[i-1]){
                            int tmp=a[i];
                            int j=i-1;
                            while(j>=0&&a[j]>tmp){
                                    a[j+1]=a[j];
                                    j--;
                            }//j为前面第一个小于tmp的下标
                            a[j+1]=tmp;
                    }
            }
    }
    /*
    冒泡排序:
    相邻两元素比较,按照要求交换顺序,共进行n-1次(原理,每次将最大值移到最后)
    时间复杂度O(n2),空间复杂度O(1),稳定
    */
    void bubbleSort(int *a,int n){
            for(int i=0;i<n;i++)
                    for(int j=0;j<n-i;j++){
                            if(a[j]>a[j+1]){
                                    int tmp=a[j];
                                    a[j]=a[j+1];
                                    a[j+1]=tmp;
                            }
                    }
    }
    /*
    简单选择排序:
    每次遍历未排序段选出最小值,插入到排序段
    时间复杂度O(n2),空间复杂度O(1),不稳定
    */
    void selectSort(int *a,int n){
            for(int i=0;i<n;i++){
                    int k=i;
                    for(int j=i;j<n;j++)
                            if(a[j]<a[k])
                                    k=j;
                    if(k!=i){//k为i---n-1中最小值的下标
                            int tmp=a[i];
                            a[i]=a[k];
                            a[k]=tmp;
                    }
            }
    }
    /*
    希尔排序:
    将数组不断分块,将块与块的对应元素进行比较后排序,重复进行直到每块只含有一个数
    有间隔的直接插入排序
    时间复杂度O(n1.3),空间复杂度O(1),不稳定
    */
    void shellSort(int *a,int n){
            int dk=n;
            while(dk/2){
                    dk/=2;
                    for(int i=dk;i<n;i++){//因为要与前dk比较,dk为起点,等价于间隔不为1的直接插入排序
                            if(a[i-dk]>a[i]){
                                    int tmp=a[i];
                                    int j=i-dk;
                                    while(j>=0&&a[j]>tmp){
                                            a[j+dk]=a[j];
                                            j-=dk;
                                    }
                                    a[j+dk]=tmp;
                            }
                    }
            }
    }
    /*
    快速排序:
    时间复杂度O(nlogn),空间复杂度O(logn),不稳定
    */
    void quickSort(int *a,int st,int ed){
            if(st>=ed)
                    return;
            int x=st,y=ed;
            int p=a[st];
            while(x<y){
                    while(x<y&&a[y]>=p)
                            y--;
                    while(x<y&&a[x]<=p)
                            x++;
                    int tmp=a[x];
                    a[x]=a[y],a[y]=tmp;
            }
            a[st]=a[x];
            a[x]=p;
            quickSort(a,st,x-1);
            quickSort(a,x+1,ed);
    }
    /*
    堆排序:
    将数组构建成大顶堆,堆顶元素为最大值,每次将堆顶元素与最后一个结点交换,然后再对前面的元素构建大顶堆,重复操作n-1次
    6 9 4 7 8 3 2 5 1 10
    1 8 4 7 6 3 2 5 9
    1 7 4 5 6 3 2 8
    2 6 4 5 1 3 7
    3 5 4 2 1 6
    1 3 4 2 5
    2 3 1 4
    1 2 3
    1 2
    1 2 3 4 5 6 7 8 9 10
    */
    void heapfy(int *a,int root,int n){//对root结点构造大顶堆
            int x=root*2+1,y=root*2+2;//左右子节点
            int mx=root;//三个节点中最大的
            if(x<n&&a[x]>a[mx])
                    mx=x;
            if(y<n&&a[y]>a[mx])
                    mx=y;
            if(mx!=root){//改变mx为下表的结点,并更新mx结点涉及的子树
                    int tmp=a[root];
                    a[root]=a[mx];
                    a[mx]=tmp;
                    heapfy(a,mx,n);
            }
    }
    void buildHeap(int *a,int n){
            for(int i=n/2-1;i>=0;i--)//含有子树的节点
                    heapfy(a,i,n);
    }
    void heapSort(int *a,int n){
            if(n==1)
                    return;
            buildHeap(a,n);
            int tmp=a[0];
            a[0]=a[n-1];
            a[n-1]=tmp;
            for(int i=0;i<n;i++){
                    printf("%d ",a[i]);
            }
            printf("
    ");
            heapSort(a,n-1);
    }
    /*
    归并排序:
    将序列不断二分直到个数为1,对比排序后再合并
    */
    void merge(int *a,int st,int mid,int ed){//对st.mid.ed两段进行排序合并
            int i=st,j=mid+1,k=0;
            int *tmp;
            tmp=(int *)malloc((ed-st+1)*sizeof(int));
            while( i<=mid && j<=ed){
                    if(a[i]<a[j])
                            tmp[k++]=a[i++];
                    else
                            tmp[k++]=a[j++];
            }
            //多余的一段直接赋值给tmp
            while(i<=mid)
                    tmp[k++]=a[i++];
            while(j<=ed)
                    tmp[k++]=a[j++];
            for(i=0;i<k;i++)
                    a[st+i]=tmp[i];
            free(tmp);
    }
    void mergeSort(int *a,int st,int ed){
            if(st>=ed){
                    return;
            }else{
                    int mid=st+ed>>1;
                    mergeSort(a,st,mid);//前半段
                    mergeSort(a,mid+1,ed);//后半段
                    merge(a,st,mid,ed);//前后半段自身排序完成后合并排序
            }
    }
    int main(){
            int a[]={6,1,2,7,9,3,4,5,10,8};
            int len=10;
            //shellSort(a,len);
            //quickSort(a,0,len-1);
            //heapSort(a,len);
            mergeSort(a,0,len-1);//0,9
            for(int i=0;i<len;i++){
                    printf("%d ",a[i]);
            }
            printf("
    ");
            return 0;
    }
    
  • 相关阅读:
    思科模拟器——常用命令
    思科模拟器——允许远程telnet连接控制路由器/交换机
    思科模拟器——使用路由器分割局域网
    如何将centos7作为DNS服务器
    Centos7设置grub密码保护
    curl提示不支持https协议解决方法
    Kettle入门--作业和转换的使用
    oracle命令导入SQL脚本
    centos7 部署elasticsearch
    Nginx通过Keepalived实现高可用
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/12285305.html
Copyright © 2020-2023  润新知