zoukankan      html  css  js  c++  java
  • 排序算法小结(一)

    排序算法的稳定性:

    如果一个待排序的序列中,存在2个相等的数,在排序后这2个数的相对位置保持不变,那么该排序算法是稳定的;否则是不稳定的。

    稳定的意义:排序算法如果是稳定的,从一个键上排序,然后从另一个键上排序,第一个键排序的结果可以为第二个键排序所用

    两个重要定理:

    定理1:任意N个不同元素组成的序列平均具有N(N-1)/4个逆序对。

    定理2:任何仅以交换相邻两元素来排序的算法,其平均时间复杂度为(N^2)

    因此要提高排序算法效率,我们必须:

      1.每次消去不止1个逆序对!

      2.每次交换相隔较远的两个元素!

    一、冒泡排序:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    #define inf 0x3fffffff
    void Bubble_Sort(int num[],int n){
        for(int i=n-1;i>0;i--){
            int flag=0;//如果序列已经有序,不需要再进行比较
            for(int j=0;j<i;j++){
                if(num[j]>num[j+1]){
                    swap(num[j],num[j+1]);
                    flag=1;
                }
            }
            if(flag==0){
                break;
            }
        }
    }
    printff(int num[],int n){
        for(int i=0;i<n;i++){
            printf("%d ",num[i]);
        }
        printf("
    ");
    }
    //冒泡排序
    //最好情况:O(n);
    //最坏情况:O(n^2);
    int main(){
        int num[maxn];
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&num[i]);
        }
        Bubble_Sort(num,n);
        printff(num,n);
        return 0;
    }

    冒泡算法是稳定的算法,因为排序前后相同元素的相对位置不变。

    交换的次数等于序列的逆序数(线代第一章有讲)

    二、插入排序

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    #define inf 0x3fffffff
    void Insertion_Sort(int num[],int n){
        int temp;
        int j;
        for(int i=1;i<n;i++){
            temp=num[i];//未排序元素
            for(j=i;j>0&&temp<num[j-1];j--){
                num[j]=num[j-1];//移出空位
            }
            num[j]=temp;//元素落位
        }
    }
    void printff(int num[],int n){
        for(int i=0;i<n;i++){
            printf("%d ",num[i]);
        }
        printf("
    ");
    }
    //插入排序
    //最好情况:O(n);
    //最坏情况:O(n^2);n(n+1)/2;
    
    int main(){
        int num[maxn];
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&num[i]);
        }
        Insertion_Sort(num,n);
        printff(num,n);
        return 0;
    }

    用一句话理解就是:将未排序的元素插入到已排序的序列中。在插入的过程中,元素往后挪。

    交换的次数等于序列的逆序数

    三、希尔排序

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    #define inf 0x3fffffff
    void Shell_Sort(int num[],int n){
        int j;
        for(int D=n/2;D>0;D/=2){//设置增量(此处增量不互质)
            for(int i=D;i<n;i++){//插入排序
                int temp=num[i];
                for(j=i;j>=D&&temp<num[j-D];j-=D){
                    num[j]=num[j-D];
                }
                num[j]=temp;
            }
        }
    }
    void printff(int num[],int n){
        for(int i=0;i<n;i++){
            printf("%d ",num[i]);
        }
        printf("
    ");
    }
    //希尔排序
    //最好情况:O(n);
    //最坏情况:O(n^2);
    
    int main(){
        int num[maxn];
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&num[i]);
        }
        Shell_Sort(num,n);
        printff(num,n);
        return 0;
    }

    注:如果增量D不互质,则小增量可能根本不起作用。

      可以用Hibbard增量序列:Dk=2^k-1  (相邻元素互质)

    四、选择排序

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    #define inf 0x3fffffff
    void Selection_Sort(int num[],int n){
        for(int i=0;i<n;i++){
            int temp=i;
            for(int j=i;j<n;j++){//从i到n中找到最小元,并将其位置赋给temp
                if(num[j]<num[temp]){
                    swap(j,temp);
                }
            }
            if(temp!=i){//将未排序部分的最小元交换到有序部分的最后位置
                swap(num[temp],num[i]);
            }
        }
    }
    void printff(int num[],int n){
        for(int i=0;i<n;i++){
            printf("%d ",num[i]);
        }
        printf("
    ");
    }
    //选择排序
    //复杂度:O(n^2)
    int main(){
        int num[maxn];
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&num[i]);
        }
        Selection_Sort(num,n);
        printff(num,n);
        return 0;
    }

    五、堆排序

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3fffffff
    const int maxn=1010;
    //heap为堆,n为元素个数
    int heap[maxn],n=100;
    //向下调整  时间复杂度为O(logn)
    void downAdjust(int low,int high){
        int i=low,j=i*2;  //i为欲调整结点,j为其左孩子
        while(j<=high){ //存在孩子结点
            if(j+1<=high&&heap[j+1]>heap[j]){//如果存在右孩子结点,且右孩子的值大于左孩子
                j=j+1;      //让j存储右孩子的下标
            }
            if(heap[j]>heap[i]){    //如果孩子中最大权值比欲调整结点i大
                swap(heap[j],heap[i]);  //交换最大权值的孩子与欲调整结点i
                i=j;    //保持i为欲调整结点,j为i的左孩子
                j=i*2;
            }
            else{
                break;  //孩子的权值均比欲调整结点i小,调整结束
            }
        }
    }
    //建堆 时间复杂度O(n)
    void creatHeap(){
        for(int i=n/2;i>=1;i--){//从最后一个非叶子结点开始枚举
            downAdjust(i,n);
        }
    }
    //删除堆顶元素 时间复杂度O(logn)
    void deleteTop(){
        heap[1]=heap[n--];  //用最后一个元素覆盖堆顶元素,并让元素个数减 1
        downAdjust(1,n);    //向下调整堆顶元素
    }
    //向上调整   时间复杂度为O(logn)
    void upAdjust(int low,int high){//对heap数组在[low,high]范围进行向上调整,其中low一般设置为1
    //high表示欲调整结点的数组下标
        int i=high,j=i/2;//i为欲调整结点,j为其父亲
        while(j>=low){  //父亲在[low,high] 范围内
            if(heap[j]<heap[i]){    //父亲权值小于欲调整结点i的权值
                swap(heap[j],heap[i]);  //交换父亲和欲调整结点
                i=j;    //保持i为欲调整结点,j为i的父亲
                j=i/2;
            }
            else{
                break;  //父亲权值比欲调整结点i的权值大,调整结束
            }
    
        }
    
    }
    //添加元素   时间复杂度O(logn)
    void insert(int x){
        heap[++n]=x;    //让元素个数加 1 ,然后将数组末位赋值为 x
        upAdjust(1,n);  //向上调整新加入的结点 n
    }
    //堆排序    时间复杂度O(nlogn)
    void heapSort(){
        creatHeap();    //建堆
        for(int i=n;i>1;i--){   //倒着枚举,直到堆中只有一个元素
            swap(heap[i],heap[1]);  //交换heap[i]与堆顶
            downAdjust(1,i-1);  //向下调整堆顶
        }
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>heap[i];
        }
        heapSort();
        for(int i=1;i<=n;i++){
            cout<<heap[i]<<" ";
        }
        cout<<endl;
        return 0;
    }
    //示例:
    //5             输入
    //3 1 4 5 2     输入
    //1 2 3 4 5     输出

    详细请看:

    六、归并排序

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    #define inf 0x3fffffff
    
    void mort(int num[],int left,int mid,int right){
        int num2[maxn];
        for(int i=left;i<=right;i++){
            num2[i]=num[i];
        }
        int i=left,j=mid+1,k=0;
        while(i<=mid&&j<=right){
            if(num2[i]<=num2[j]){
                num[left+k]=num2[i];
                k++;
                i++;
            }
            else{
                num[left+k]=num2[j];
                k++;
                j++;
            }
        }
        while(i<=mid){
            num[left+k]=num2[i];
            i++;
            k++;
        }
        while(j<=right){
            num[left+k]=num2[j];
            j++;
            k++;
        }
    }
    void GBsort(int num[],int left,int right){
        if(left>=right){
            return ;
        }
        int mid=(left+right)/2;
        GBsort(num,left,mid);//递归处理左子序列
        GBsort(num,mid+1,right);//递归处理右子序列
        mort(num,left,mid,right);//合并左右子序列
    }
    void printff(int num[],int n){
        for(int i=0;i<n;i++){
            printf("%d ",num[i]);
        }
        printf("
    ");
    }
    //归并排序
    //复杂度:nlogn
    int main(){
        int num[maxn];
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&num[i]);
        }
        GBsort(num,0,n-1);
        printff(num,n);
        return 0;
    }

    明天继续。。。

  • 相关阅读:
    org.springframework.beans.BeanUtils属性赋值 Date类型处理转换为LocalDateTime, Date不能直接赋值给LocalDateTime
    python rabbitmq官方文档demo
    rabbitmq安装
    python 文件查找及截取字符串 (替换,分割) demo
    python pika rabbitmq demo
    python xlrd excel读取操作
    python pymysql 数据库查询操作
    GO语言学入门学习,学习资料推荐
    linux安装uwsgi错误:gcc returned 1 exit status error: lto-wrapper failed collect2:
    anconda的使用以及在conda环境中使用pip和conda使用安装依赖的区别和注意事项
  • 原文地址:https://www.cnblogs.com/dreamzj/p/14615288.html
Copyright © 2011-2022 走看看