排序 - 冒泡、选择、插入、归并、快排、堆、希尔、计数、基数

简单排序 - 冒泡、选择、插入

1. 冒泡排序

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

2. 选择排序

class SelectionSort {
public:
    int* selectionSort(int* A, int n) {
        int flag=0;
        for(int i=0; i<n; i++){
            int min=100000;
            for(int j=i; j<n; j++){
                if(A[j]<min){
                    min=A[j];
                    flag=j;
                }
            }
            int tmp=A[i];
            A[i]=A[flag];
            A[flag]=tmp;
        }
        return A;
    }
};

3. 插入排序

class InsertionSort {
public:
    int* insertionSort(int* A, int n) {
        for(int i=1; i<n; i++){               
            for(int j=i; j>0; j--){
                if(A[j]<A[j-1]){
                    int tmp=A[j-1];
                    A[j-1]=A[j];
                    A[j]=tmp;
                }
            }
        }
        return A;
    }
};

 

排序进阶

1. 归并排序

对于一个int数组,请编写一个归并排序算法,对数组元素排序。

给定一个int数组A及数组的大小n,请返回排序后的数组。

测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

代码:

class MergeSort{
public:
    void Merge(int* A, int* tmpA, int L, int R, int RightEnd)   //归并
    {
        int LeftEnd=R-1;
        int Tmp=L;
        int num=RightEnd-L+1;
        while(L<=LeftEnd && R<=RightEnd){
            if(A[L]<=A[R])
                tmpA[Tmp++]=A[L++];
            else
                tmpA[Tmp++]=A[R++];
        }
        while(L<=LeftEnd)
            tmpA[Tmp++]=A[L++];
        while(R<=RightEnd)
            tmpA[Tmp++]=A[R++];
        for(int i=0; i<RightEnd; i++)
            A[i]=tmpA[i];
    }
     
    void divide(int* A, int* tmpA, int n, int length)   //划分 (非递归)
    {
        int i;
        for(i=0; i<n-length*2; i+=2*length)   //length为当前有序子列的长度 |156|234|:3  
            Merge(A, tmpA, i, i+length, i+length*2-1);
         
        //循环中把要归并的最后一组(length*2 or length)单独提出来,因为该组可能没有满
        if(i+length<n)   //还剩两个子列
            Merge(A, tmpA, i, i+length, n-1);
        else {           //还剩1个子列
            for(int j=i; j<n; j++) 
		    tmpA[j]=A[j];
        }
    }
     
    int* mergeSort(int* A, int n) {
        int *tmpA = new int[n];
        int length=1;
        while(length<n){  //length为有序子列的长度 <n 才对其操作
            divide(A,tmpA,n,length);
            length*=2;
            divide(tmpA,A,n,length);
            length*=2;
        }
        delete tmpA;
        return A;
    }
};

 

2. 快速排序 

对于一个int数组,请编写一个快速排序算法,对数组元素排序。

给定一个int数组A及数组的大小n,请返回排序后的数组。

测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

代码:

class QuickSort {
public:
    void Qsort(int* A, int l, int r) {
        if(l>=r)
            return;
        else{
            int i=l, j=r, x=A[l];
            while (i<j){
                while(i<j && A[j]>=x)   //从右向左找第一个小于x的数
                    j--; 
                if(i<j)
                    A[i]=A[j];		  //若此处为 A[i++]=A[j] => 数组越界
             
                while(i<j && A[i]<x)    //从左向右找第一个大于等于x的数
                    i++; 
                if(i<j)
                    A[j]=A[i];
            }
            A[i]=x;
            Qsort(A, l, i-1);    // 递归调用
            Qsort(A, i+1, r);
        }
    }
 
    int* quickSort(int* A, int n) {
        Qsort(A,0,n-1);
        return A;
    }
};

 

3. 堆排序

对于一个int数组,请编写一个堆排序算法,对数组元素排序。

给定一个int数组A及数组的大小n,请返回排序后的数组。

测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

代码:

class HeapSort {
public:
    void swap(int* A, int i, int j) {
        int tmp=A[i];
        A[i]=A[j];
        A[j]=tmp;
    }

    void sink(int* A, int k, int n) {
        while(k*2+1<=n){    		//k有子节点
            int j=k*2+1;   		 //j表示其子节点
            if(j<n && A[j+1]>A[j])    	//j指向左右孩子中大的
                j++;
            if(A[k]>A[j])
                break;
            swap(A,k,j);
            k=j;
        }
    }

    int* heapSort(int* A, int n) {
        n--;    //最后一个元素是A[n-1]
        for(int parent=(n-1)/2; parent>=0; parent--)	  //建大顶堆
            sink(A,parent,n);
        while(n>0){
            swap(A,0,n--);
            sink(A,0,n);
        }
        return A;
    }
};

 

4. 希尔排序

对于一个int数组,请编写一个希尔排序算法,对数组元素排序。

给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素小于等于2000。

测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

代码:

class ShellSort {
public:
    int* shellSort(int* A, int n) {
        for(int pace=n/2; pace>0; pace/=2){   //步长变换
            for(int i=pace; i<n; i+=pace){
                for(int j=i; j-pace>=0; j-=pace){
                    if(A[j]<A[j-pace]){
                        int tmp=A[j];
                        A[j]=A[j-pace];
                        A[j-pace]=tmp;
                    }
                }
            }
        }
        return A;
    }
};

 

5. 计数排序

对于一个int数组,请编写一个计数排序算法,对数组元素排序。

给定一个int数组A及数组的大小n,请返回排序后的数组。

测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

代码:

class CountingSort {
public:
    int* countingSort(int* A, int n) {
        int min=A[0], max=A[0];
        for(int i=1; i<n; i++){   //找桶的数量
            if(A[i]>max) max=A[i];
            if(A[i]<min) min=A[i];
        }
        int cnt=max-min+1;
        vector<int> b(cnt, 0);    //初始化桶
        for(int j=0; j<n; j++){   //装桶
            b[A[j]-min]++;        //A[]中的数对应的桶中的数量++
        }
        int it=0;   //A的下标
        for(int k=0; k<cnt; k++){
            while(b[k]-- > 0)    //b(桶)中为该数据出现的次数
                A[it++]=k+min;   //数据 = b的下标 + min
        }
        return A;
    }
};

 

6. 基数排序

对于一个int数组,请编写一个基数排序算法,对数组元素排序。

给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素均小于等于2000。

测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

代码:

class RadixSort {
public:
    int get(int a, int exp) {
        int b = a / (pow(10,exp));
        return b % 10;
    }
     
    int* radixSort(int* A, int n) {
        int maxd=0;
        for(int it=0; it<n; it++){
            if(A[it]>maxd)
                maxd=A[it];
        }
        int time=0;
        while(maxd){
            time++;
            maxd/=10;
        }               //得到最大的数有几位  

        queue<int> B[10];
        for(int i=0; i<time; i++){
            for(int j=0; j<n; j++){
                int x=get(A[j], i);
                B[x].push(A[j]);
            } 
            int index=0;
            for(int k=0; k<10; k++){
                for(unsigned int t=0; t<B[k].size(); ){
                    A[index++]=B[k].front();
                    B[k].pop();
                }
            }
        }
        return A;
    }
};

 

posted @ 2016-05-16 18:02  claremz  阅读(303)  评论(0编辑  收藏  举报