zoukankan      html  css  js  c++  java
  • 四种nlogn排序算法代码

    1.快速排序:不稳定排序,最好情况O(nlogn),最差情况O(n^2).平均情况在所有nlogn排序中最快的排序

    快速排序分两步
    第一步是将l-r区间进行分块(假设将区间最后一个作为关键字)前面一块的数比小于等于关键字,后面一块大于关键字,并返回第一个大于关键字的位置,即函数partition
    第二部是对l~pos-1 和pos+1~r分别进行快速排序.

    递归式:
    int partition(int l,int r)
    {
        int k=r;
        while(l<r)
        {
            int c=0;
            if(a[l]<=a[k])
                l++;
            else
                c++;
            if(a[r]>=a[k])
                r--;
            else
                c++;
            if(c==2)
            {
                int tem=a[l];
                a[l]=a[r];
                a[r]=tem;
            }
        }
        if(l==r)
        {
            if(a[k]>=a[r])
                return r+1;
            else
                return r;
        }
        else
            return l;

    }
    void quicksort(int l,int r)
    {
        if(l>=r)
            return;
        int pos;
        pos=partition(l,r);
        int val=a[r];
        a[r]=a[pos];
        a[pos]=val;
        quicksort(l,pos-1);
        quicksort(pos+1,r);
    }

    非递归式:
    用栈实现,在函数各种变量和参数不是很多的情况下用递归式比较好
    详细看网上

    2.shell排序:不稳定排序,最好情况O(nlogn),最差情况O(n^x),1<x<2
    变长度的插入排序,分别对原数组进行k次长度不同的插入排序即可,注意:最后一次必须是长度为1的插入排序
    void shellsort()
    {
        for(int i=0;i<=x;i++)//x代表长度的组数
        {
            for(int j=len[i];j<n;j++)//此处是j++而不是j+=len[i]注意!!,希尔排序变长度的排序思想
            {
                int k=j-len[i];
                while(k>=0)
                {
                    if(a[j]<a[k])
                    {
                        int tem=a[j];
                        a[j]=a[k];
                        a[k]=tem;
                        break;
                    }
                    else
                        k-=len[i];
                }
            }
        }
    }

    3.堆排序:不稳定排序,最好和最坏的时间复杂度均为O(nlogn):
    主要是写向下渗透函数,然后注意:
    1.当数组从0开始左儿子为2*x+1,右儿子为2*x+2
    递归返回条件i》(x+1)/2-1
    2.当数组从1开始左儿子为2*x,右儿子为2*x+1
    递归返回条件i》(x+1)/2
    class heaps
    {
    public:
        int heap[50]={9,8,7,6,5,4,3,2,1,34,5,6,74,24,5,1,2,3,4,55,21,13,41,3};
        int maxsize=23;
        void godown(int i,int x)
        {
            if(i>(x+1)/2-1)//返回条件,易错点
                return;
            int MAX;
            int j;
            if(i*2+2>x)//当只有左孩子的情况!!易错点
            {
                MAX=heap[i*2+1];
                j=i*2+1;
            }
            else//有两个孩子的情况
            {
                if(heap[i*2+1]>heap[i*2+2])
                {
                    MAX=heap[i*2+1];
                    j=i*2+1;
                }
                else
                {
                    MAX=heap[i*2+2];
                    j=i*2+2;
                }
            }
            if(MAX>heap[i])
            {
                heap[j]=heap[i];
                heap[i]=MAX;
                godown(j,x);
            }

        }
        void buildheap()
        {
            for(int i=(maxsize+1)/2-1;i>=0;i--)
                godown(i,maxsize);
        }
        void heapsort()
        {
            int k=maxsize;
            for(int i=1;i<=maxsize;i++)
            {
                int tem=heap[k];
                heap[k]=heap[0];
                heap[0]=tem;
                k--;
                godown(0,k);//注意,堆的大小在不断变化
            }
        }
    };

    4.归并排序:稳定排序,最好和最坏的时间复杂度均为O(nlogn)

    void merge(int* a,int l,int r)
    {
        int tem[100];
        int mid=(l+r)/2;
        int i=l;
        int j=mid+1;
        int k=l;
        for(;i<=mid+1||j<=r+1;i++,j++)
        {
            if(i==mid+1&&j==r+1)
                break;
            if(i==mid+1)
            {
                tem[k++]=a[j];
                i--;
                continue;
            }
            if(j==r+1)
            {
                tem[k++]=a[i];
                j--;
                continue;
            }
            if(a[i]<a[j])
            {
                tem[k++]=a[i];
                j--;
            }
            else
            {
                tem[k++]=a[j];
                i--;
            }
        }
    }
    void merge_sort(int* a,int l,int r)
    {
        int mid=(l+r)/2;
        if(mid+1>r)
            return;
        merge_sort(a,l,mid);
        merge_sort(a,mid+1,r);
        merge(a,l,r);
    }

    此外还有3种O(n^2)的排序,不详细介绍
    1.选择排序:不稳定,时间复杂度 O(n^2)
    2.插入排序:稳定,时间复杂度 O(n^2)
    3.冒泡排序:稳定,时间复杂度 O(n^2)

  • 相关阅读:
    winform窗口打开特效及窗口位置居中
    C# Installer Projects 打包工具
    C#
    MVVM模式开发WinForm-ReactiveUI
    C#实现类似百度网盘、育网校园云盘在“我的电脑”磁盘驱动器
    MVVM框架
    自制2048小游戏
    一个无限循环轮播图 HCCycleView
    Xcode插件及cocoapods不能正常使用的解决方法
    Runtime — 运行时机制
  • 原文地址:https://www.cnblogs.com/wzsblogs/p/4330673.html
Copyright © 2011-2022 走看看