经典排序算法总结----模板(C++实现)

1.选择排序

template <typename T>     //选择排序
void Selectionsort(T arr[],int n){
    for(int i=0;i<n;i++){
        int minIndex =i;
            for(int j=i+1;j<n;j++){
                if(arr[j]<arr[minIndex])
                minIndex = j;
            }
            swap(arr[i],arr[minIndex]);
    }
}

2.插入排序

template <typename T>  //插入排序
void Insertsort(T arr[],int n){
    for(int i=1;i<n;i++){ 
        for(int j=i;j>0;j--){ //j=1时与j=0 进行比较!
            if(arr[j]<arr[j-1])
                swap(arr[j],arr[j-1]);
            else 
                break;
        }
        }
}

插入排序改进版-优化时间复杂度

template<typename T> // 插入排序改进
void InsertsortG(T arr[],int n){
    for(int i=1;i<n;i++){
        T e = arr[i];
        int j;
        for( j=i;j>0&&arr[j-1]>e;j--){
            arr[j]=arr[j-1];
        }
        arr[j] = e;
}
}

3.归并排序

template<typename T> //归并排序
void meregesort(T arr[],int qaq,int qbq){
    __mergesort(arr,qaq,qbq-1);
}
template<typename T>//递归对[l,r]进行排序
void __mergesort(T arr[],int l,int r){
    if(l>=r)
        return ;
    int mid = (l+r)/2;
    __mergesort(arr,l,mid);
    __mergesort(arr,mid+1,r);
    if(arr[mid]>arr[mid+1]) //对归并排序进行优化可加上此条件
        __merge(arr,l,mid,r);
}
template<typename T>//对[l,mid]和[mid+1,r]进行归并
void __merge(T arr[],int l,int mid,int r){
    T aux[r-l+1];
    for(int t=l;t<=r;t++)
    aux[t-l] = arr[t];
    int i = l, j = mid+1;
    for(int k=l;k<=r;k++){
        if(i>mid){
            arr[k] = aux[j-l];
            j++;
        }
        else if(j>r){
            arr[k] = aux[i-l];
            i++;
        }
        else if(aux[i-l]<aux[j-l]){
            arr[k] = aux[i-l];
            i++;
        }
        else{
            arr[k] = aux[j-l]; 
            j++;       
        }

    }
}

4.一般快速排序

//对arr[l,r]进行partition操作
//返回p 使得arr[l,p-1]<arr[p],arr[p+1,r]>arr[p]
template<typename T>
int _partition(T arr[],int l,int r){
    swap(arr[l],arr[rand()%(r-l+1)+l]);
    //对快速排序进行优化
    T v = arr[l];
    //arr[l+1,j]<v;arr[j+1,i] >= v 
    int j = l; //上述两个区间为空
    for(int i= l+1;i<=r;i++){
        if(arr[i]<v){
            swap(arr[j+1],arr[i]);
            j++;
            //swap(arr[++j],arr[i]);
        }
    }
    swap(arr[l],arr[j]);
    return j;
}
template<typename T>
void __quick_sort(T arr[],int l,int r){
    if(l>=r)
        return;
    int p = _partition(arr,l,r);
    __quick_sort(arr,l,p-1);
    __quick_sort(arr,p+1,r);
}
template<typename T>
void quick_sort(T arr[],int a,int b){
    srand(time(NULL));//为了优化快速排序
    __quick_sort(arr,a,b-1);
}

5.二路快速排序

template<typename T>
int _partition2(T arr[],int l,int r){
    swap(arr[l],arr[rand()%(r-l+1)+1]);
    //对快速排序进行优化
    T v = arr[l];
    //arr[l+1,j]=<v;arr[j+1,i] >=v
    int i =l+1; 
    int j = r; //上述两个区间为空
    while(true){
        while(i<=r && arr[i]<v)  i++;
        while(j>=l+1 && arr[j]>v) j--;
        if(i>j) break;
        swap(arr[i],arr[j]);
        i++;
        j--;;
        }
    swap(arr[l],arr[j]);
    return j;
}
template<typename T>
void __quick_sort2(T arr[],int l,int r){
    if(l>=r)
        return;
    int p = _partition2(arr,l,r);
    __quick_sort2(arr,l,p-1);
    __quick_sort2(arr,p+1,r);
}
template<typename T>
void quick_sort2(T arr[],int a,int b){
    srand(time(NULL));//为了优化快速排序
    __quick_sort2(arr,a,b-1);
}

6.三路快速排序

template<typename T>
void __quick_sort3ways(T arr[],int l,int r){
    if(l>=r)
        return;
    //partition
    swap(arr[l],arr[rand()%(r-l+1)+l]);
    T v =arr[l];
    int lt =l;//arr[l+1..lt]<v
    int gt =r+1;//arr[gt..r]>v
    int i =l+1;//arr[lt+1..i]==v
    while(i<gt){
        if(arr[i]<v){
            swap(arr[i],arr[lt+1]);
            lt++;
            i++;
        }
        else if(arr[i]>v){
            swap(arr[i],arr[gt-1]);
            gt--;
        }
        else{//arr[i]==v
            i++;
        }
    }
    swap(arr[l],arr[lt]);
    __quick_sort3ways(arr,l,lt-1);
    __quick_sort3ways(arr,gt,r);
}
template<typename T>
void quick_sort3ways(T arr[],int a,int b){
    srand(time(NULL));
    __quick_sort3ways(arr,a,b-1);
}

7.堆排序

template<typename Item>
class MaxHeap{
    private:
        Item *data;
        int count;
        int capacity;
        void ShiftUp(int k){
            //插入一个数据保证它是大根堆
            while(k>1 && data[k/2]<data[k]){
                swap(data[k/2],data[k]);
                k/=2;
            }
        }
        void ShiftDown(int k){
            //调整为大根堆
            while(2*k<=count){
                int j = 2*k; //这个循环中data[k]和data[j]交换位置
                if(j+1<=count && data[j+1] > data[j]) 
                //判断是否有右孩子 以及 是否右孩子大于左孩子
                    j+=1;
                if(data[k]>=data[j])
                    break;   
                //退出循环
                swap(data[k],data[j]);
                k = j;
            }

        }
    public:
        MaxHeap(int capacity){
            data = new Item[capacity];
            count = 0;
            this->capacity = capacity;
        }
        MaxHeap(Item arr[],int n){
            data = new Item[n+1];
            capacity = n;
            for(int i = 0 ;i < n; i++)
                data[i+1]=arr[i];
            count = n;
            for(int i=count/2 ;i>=1;i--)
                ShiftDown(i);
        }
        int size(){
            return count;
        }
        bool isEmpty(){
            return count == 0;
        }

        void insert(Item item){
            //插入操作(调整为一个大根堆)
            assert(count+1<=capacity);
            data[count+1] = item;
            count ++;
            ShiftUp(count);
        }
        Item extractMax(){//取出最大值
            assert(count>0);
            
            Item ret = data[1];

            swap(data[1],data[count]);
            count--;
            ShiftDown(1);
            return ret;
        }
        ~MaxHeap(){
            delete []data;
        }
};
template<typename T>
void HeapSort1(T arr[],int a,int b){//堆排序
    assert(b-a>=0);
    int n = b-a+1;
    MaxHeap<T> maxheap = MaxHeap<T>(n);
    for(int i=0;i<n;i++)
        maxheap.insert(arr[i]);
        //一个一个插入成为大根堆 消耗时间,新方法 heapify
    for(int i=n-1;i>=0;i--)
        arr[i] = maxheap.extractMax();
}

template<typename T> //heapify方法
void HeapSort2(T arr[],int a,int b){//堆排序改进
    assert(b-a>=0);
    int n = b-a+1;
    MaxHeap<T> maxheap = MaxHeap<T>(arr,n);
       
    for(int i=n-1;i>=0;i--)
        arr[i] = maxheap.extractMax();
}
//以上堆排序 需要额外空间
template<typename T>
void __ShiftDown2(T arr[],int n,int k){
            //n个元素 K索引向下
            //调整为大根堆
     while(2*k+1 < n){//因为数组是从0开始
         int j = 2*k+1; //这个循环中data[k]和data[j]交换位置
         if(j+1< n && arr[j+1] > arr[j]) 
                //判断是否有右孩子 以及 是否右孩子大于左孩子
            j+=1;
         if(arr[k]>=arr[j])
            break;   
                //退出循环
        swap(arr[k],arr[j]);
        k = j;
            }
}
template<typename T> 
void HeapSort(T arr[],int a,int b){
    assert(b-a>=0);
    int n = b-a+1;
    // 从(最后一个元素的索引-1)/2开始    
    // 最后一个元素的索引 = n-1    
    for( int i = (n-1-1)/2 ; i >= 0 ; i -- )    
        __ShiftDown2(arr, n, i);    
        //heapify操作
     
    for( int i = n-1; i > 0 ; i-- ){    
        swap( arr[0] , arr[i] );    
        __ShiftDown2(arr, i, 0);    
    }    
}


//...........
//...........
//索引堆
//...........
//...........
template<typename Item>
class IndexMaxHeap{
    private:
        Item *data;
        int *indexes;
        int count;
        int capacity;
        void ShiftUp(int k){
            //插入一个数据保证它是大根堆
            while(k>1 && data[indexes[k/2]]<data[indexes[k]]){
                swap(indexes[k/2],indexes[k]);
                k/=2;
            }
        }
        void ShiftDown(int k){
            //调整为大根堆
            while(2*k<=count){
                int j = 2*k; //这个循环中data[k]和data[j]交换位置
                if(j+1<=count && data[indexes[j+1]] > data[indexes[j]]) 
                //判断是否有右孩子 以及 是否右孩子大于左孩子
                    j+=1;
                if(data[indexes[k]]>=data[indexes[j]])
                    break;   
                //退出循环
                swap(indexes[k],indexes[j]);
                k = j;
            }

        }
    public:
        MaxHeap(int capacity){
            data = new Item[capacity+1];
            indexes = new int[capacity+1]
            count = 0;
            this->capacity = capacity;
        }
        MaxHeap(Item arr[],int n){
            data = new Item[n+1];
            capacity = n;
            for(int i = 0 ;i < n; i++)
                data[i+1]=arr[i];
            count = n;
            for(int i=count/2 ;i>=1;i--)
                ShiftDown(i);
        }
        int size(){
            return count;
        }
        bool isEmpty(){
            return count == 0;
        }
//传入的I用户是数组从0开始,其实堆从1开始
        void insert(int i,Item item){
            //插入操作(调整为一个大根堆)
            assert(i+1>=1 && i+1<=capacity);
            assert(count+1<=capacity);
            i += 1;
            data[i] = item;
            indexes[i] = i;

            count ++;
            ShiftUp(count);
        }
        Item extractMax(){//取出最大值
            assert(count>0);
            
            Item ret = data[indexes[1]];

            swap(indexes[1],indexes[count]);
            count--;
            ShiftDown(1);
            return ret;
        }
        int extractMax(){//取出最大值
            assert(count>0);
            
            int ret = indexes[1]-1;

            swap(indexes[1],indexes[count]);
            count--;
            ShiftDown(1);
            return ret;
        }
        Item getItem(int i){
            return data[i+1];
        }
        void change(int i,Item newItem){
            //修改索引为i的Item
            i += 1;
            data[i] = newItem;
            //找出indexes[j] = i; j表示data[i]在堆中的位置
            //shiftup(j) shiftdown(j)
            for(int j=1;j<=count;j++){
                if(indexes[j]==i){
                    ShiftUP(j);
                    ShiftDown(j);
                    return;
                }
            }
        }
        ~MaxHeap(){
            delete []data;
            delete []indexes;
        }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值