各种排序算法的C++实现

来源:互联网 发布:莫文蔚周星驰知乎 编辑:程序博客网 时间:2024/06/01 09:37

冒泡排序
两两交换,稳定排序
时间复杂度O(n2)
空间复杂度O(1)

class BubbleSort {public:    int* bubbleSort(int* A, int n) {        for(int i=0;i!=n-1;++i)            {            for(int j=0;j!=n-1-i;++j)                {                if(A[j]>A[j+1])                    {                    int temp;                    temp=A[j];                    A[j]=A[j+1];                    A[j+1]=temp;                }            }        }        return A;    }};

选择排序 时间复杂度O(n2)
选择最小和第一个位置交换,之后第二个位置以后选择最小和第二个位置交换。
不稳定排序
空间复杂度O(1)

class SelectionSort {public:    int* selectionSort(int* A, int n) {        int temp;        int pos;        for(int i=0;i!=n;++i)            {            temp=A[i];            pos=i;            for(int j=i+1;j!=n;++j)            {            if(temp>A[j])                {                temp=A[j];                pos=j;            }        }             if(pos!=i)                 swap(A+pos,A+i);        }        return A;        // write code here    }    void swap(int *a,int *b)        {        int temp;        temp=*a;        *a=*b;        *b=temp;    }};

插入排序 时间复杂度O(n2)
从后向前比较代码比较简单
稳定排序
空间复杂度O(1)

class InsertionSort {public:    int* insertionSort(int* A, int n) {        for(int i=1;i!=n;++i)            {            if(A[i]<A[i-1])                {                int temp=A[i];                int j=i-1;                A[i]=A[i-1];                int pos=i-1;             while(j)                 {                 if(temp<A[j-1])                     {                     A[j]=A[j-1];                     pos=j-1;                 }                                  --j;             }             A[pos]=temp;                             }        }        return A;        // write code here    }};

归并排序 时间复杂度O(nlgn) 空间复杂度O(n)
稳定排序
空间复杂度O(n)

class MergeSort {public:    int* mergeSort(int* A, int n) {        int *temp=new int[n];        mergerecur(A,0,n-1,temp);        return A;                // write code here    }    void mergerecur(int *input,int first,int end,int *temp)        {        if(end>first)            {            int mid=(first+end)/2;            mergerecur(input,first,mid,temp);            mergerecur(input,mid+1,end,temp);            mergearray(input,temp,input+first,mid-first+1,input+mid+1,end-mid);        }           }    void mergearray(int *input,int *res,int *a,int lena,int *b,int lenb)        {        int first=a-input;        int i=0;        int j=0;        int k=0;       while(i!=lena&&j!=lenb)            {            if(a[i]<b[j])                res[k++]=a[i++];            else                res[k++]=b[j++];                         }         while(j!=lenb)            res[k++]=b[j++];                    while(i!=lena)            res[k++]=a[i++];         for(int i=0;i!=k;++i)            input[first++]=res[i];    }};

快速排序 平均时间复杂度O(nlgn) 空间复杂度O(nlgn)
空间复杂度O(N)~O(logN)
不稳定排序

class QuickSort {public:    int* quickSort(int* A, int n) {        sortrecur(A,0,n-1);        return A;        // write code here    }    void sortrecur(int *a,int l,int r)        {        if(l<r)        {        int mid=sortmove(a,l,r);        sortrecur(a,l,mid-1);        sortrecur(a,mid+1,r);        }    }    int sortmove(int *a,int l,int r)        {        int i=l;        int j=r;        int x=a[i];        while(i<j)            {           while(i<j&&a[j]>=x)                  --j;             a[i]=a[j];           while(i<j&&a[i]<=x)                  ++i;             a[j]=a[i];        }        a[i]=x;        return i;    }};

堆排序 时间性能O(nlgn) 空间性能O(1)
不稳定排序
利用最大或最小堆进行排序
核心思想首先将序列构建成最大堆或者最小堆,之后选择最大堆顶部元素和最后一个元素交换
之后无序序列长度减1,重新构建最大堆最小堆,迭代上述步骤即可完成整个排序过程和选择排序有些类似,注意其有序序列从后端向前端生长。
空间复杂度O(1)

class HeapSort {public:    int* heapSort(int* A, int n) {        // write code here        sortrecur(A,n);        return A;    }    void sortrecur(int *a,int lena)        {        if(lena>1){        buildheap(a,lena);        swapnum(a,a+lena-1);        sortrecur(a,lena-1);        }    }    void buildheap(int *a,int lena)        {        if(lena<2)            return;        for(int i=(lena-2)/2;i>=0;--i)            {            if(a[i]<a[2*i+1])                swapnum(a+i,a+2*i+1);            if(2*i+2<lena)                {                if(a[i]<a[2*i+2])                    swapnum(a+i,a+2*i+2);            }        }    }    void swapnum(int *a,int *b)        {        int temp;        temp=*a;        *a=*b;        *b=temp;    }};

希尔排序
希尔增量时间复杂度为O(n²),而Hibbard增量的希尔排序的时间复杂度为O(n3/2),希尔排序时间复杂度的下界是n*log2n。
空间复杂度O(1)
不稳定排序

class ShellSort {public:    int* shellSort(int* A, int n) {        sortrecur(A,n,n/2);        return A;        // write code here    }    void sortrecur(int *a,int n,int dk)        {        if(dk>0){          shellinsert(a,n,dk);           dk=dk/2;          sortrecur(a,n,dk);        }          }    void shellinsert(int *a,int n,int dk)        {        for(int i=0;i<dk;++i) //所有组数            {                for(int j=i+dk;j<n;j+=dk) //插入排序                    {                    int k=j;                    int temp=a[k];                                      while(k-dk>=i&&temp<a[k-dk])//先判断下标再比较大小,否则还会内存越界                        {                         a[k]=a[k-dk];                         k=k-dk;                    }                    a[k]=temp;                }        }    }};

计数排序
桶排序的一种时间复杂度O(n),空间复杂度O(M)(取决于桶的个数)
适合数字在一定范围内的排序。
稳定排序

class CountingSort {public:    int* countingSort(int* A, int n) {        int max=A[0];        int min=A[0];        for(int i=0;i!=n;++i)            {            if(min>A[i])                min=A[i];            if(max<A[i])                max=A[i];        }        int *bucket=new int[max-min+1];        memset(bucket,0,(max-min+1)*sizeof(int));        for(int i=0;i!=n;++i)            {            ++(*(bucket+A[i]-min));        }        int pos=0;        for(int i=0;i!=max-min+1;++i)            {            int k=*(bucket+i);            while(k--)                {                *(A+pos)=i+min;                ++pos;            }        }        return A;        // write code here    }};

基数排序
其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,
稳定排序

class RadixSort {public:    int* radixSort(int* A, int n) {        vector<queue<int>> vec_pos(10,queue<int>{});        vector<queue<int>> vec_neg(10,queue<int>{});        int max=abs(A[0]);        for(int i=0;i!=n;++i)            {            if(max<abs(A[i]))                max=abs(A[i]);        }        int i=1;        while(max/10)               {                   ++i;                   max=max/10;               }        int k=i;        while(i--)            {            int div=1;            int num=k-i-1;            while(num--)                div=div*10;                           for(int j=0;j!=n;++j)                {                if(A[j]>=0)                vec_pos[(A[j]/div)%10].push(A[j]);                else                {                vec_neg[(0-(A[j])/div)%10].push(A[j]);                  }            }            int pos=0;            for(int neg_iter=vec_neg.size()-1;neg_iter>=0;--neg_iter)            {                while(!vec_neg[neg_iter].empty())                {                A[pos]=vec_neg[neg_iter].front();                vec_neg[neg_iter].pop();                ++pos;                }                      }           for(int pos_iter=0;pos_iter!=10;++pos_iter)               {                while(!vec_pos[pos_iter].empty())                {                A[pos]=vec_pos[pos_iter].front();                vec_pos[pos_iter].pop();                ++pos;                }            }        // write code here    }        return A;    }};
0 0