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

 

#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;
}
原文地址:https://www.cnblogs.com/aeipyuan/p/12285305.html