一些排序算法

一些排序算法

 

头文件

/*************************

        交换排序

**************************/

//冒泡排序

void BubbleSort(vector<int> &v,int begin,int end);

//快速排序

void QuickSort(vector<int> & v,int begin,int end);







/************************

        插入排序

*************************/

//直接插入排序

void InsertionSort(vector<int> &v,int begin,int end);

//折半插入排序

void BinaryInsertSort(vector<int> &v,int begin,int end);

//希尔排序

void ShellSort(vector<int> & v,int begin,int end);







/************************

        选择排序

*************************/

//直接选择排序

void SelectSort(vector<int> & v,int begin,int end);

//锦标赛排序

void ChamptionSort(vector<int> & v,int begin,int end);

//堆排序

void HeapSort(vector<int> &v,int begin,int end);





/************************

        归并排序

*************************/

//递归的两路归并

void MergeSort(vector<int> & v,int begin,int end);



/***********************

        基数排序

***********************/

void RadixSort(vector<int> & v,int begin,int end);

实现源文件

#include "StdAfx.h"

#include "Sorts.h"

#include <MATH.H>





int getpositionvalue(list<int> & ilist,int pos){

    list<int>::iterator it = ilist.begin();

    while(pos-- >0)

        ++it;

    

    return *it;

}



void setpositionvalue(list<int> & ilist,int pos,int value){

    list<int>::iterator it = ilist.begin();

    while(pos-- >0)

        ++it;

    ilist.insert(it,value);

}

//冒泡排序

void BubbleSort(vector<int> &v,int begin,int end){

    

    int i = 0;

    int j = 0;

    int sorted = 0;  //后面的已经排好的位数,接下来就不用再比较了

    for(i = begin;i < end;i++){

        for(j = begin;j < end-sorted;j++){

            if(v[j] > v[j+1]){

                int temp = v[j+1];

                v[j+1] = v[j];

                v[j] = temp;

            }

        }

        sorted++;

    }    

}





//快速排序



int Partition(vector<int> & v,int begin,int end){

    int i = begin;

    int j = end;

    int key = v[begin];

    while(i<j){

        while(v[j] >= key && i<j)      //从后往前找到第一个比key小的

            j--;

        v[i] = v[j];

        

        while(v[i] < key && i<j)       //从前往后找到比key大的

            i++;

        v[j] = v[i];

    }

    v[i] = key;

    return i;

}



void QuickSort(vector<int> & v,int begin,int end){

    if(begin < end){

        int tempindex = Partition(v,begin,end);

        QuickSort(v,begin,tempindex);

        QuickSort(v,tempindex+1,end);

    }

}



//直接插入排序

void InsertionSort(vector<int> &v,int begin,int end){

    list<int> ilist;

    ilist.push_back(v[begin]);

    

    int i = begin+1;

    list<int>::iterator it = ilist.begin();

    for( ;i<=end;i++){

        int flag = 0;

        for(it = ilist.begin();it!=ilist.end();it++){

            if(v[i] < *it){

                ilist.insert(it,v[i]);

                flag = 1;         // 代表已在前面插入,否则需要在后面push_back

                break;            // 插入之后就得退出了

            }

        }

        if(flag == 0)

            ilist.push_back(v[i]);

    }

    for( it = ilist.begin();it!=ilist.end();it++,begin++){

        v[begin] = *it;

    }

}



//折半插入排序 (插入比较时,用二分查找法)

void BinaryInsertSort(vector<int> &v,int begin,int end){

    list<int> ilist;

    ilist.push_back(v[begin]);

    

    int i = begin+1;

    list<int>::iterator it = ilist.begin();

    for( ;i<=end;i++){

        

        int tempbegin = 0;

        int tempend = ilist.size()-1;

        while(tempbegin <= tempend){

            int mid = (tempbegin+tempend)/2 ;

            if(getpositionvalue(ilist,mid) > v[i]){

                tempend = mid-1;

            }

            else

                tempbegin = mid+1;

        }

        if(tempbegin <= ilist.size()-1){         //说明比v[i]大的元素还在list中,在内部插入

            setpositionvalue(ilist,tempbegin,v[i]);

        }

        else                                    //否则push_back,在最后面插入

            ilist.push_back(v[i]);

    }

    for( it = ilist.begin();it!=ilist.end();it++,begin++){

        v[begin] = *it;

    }

}

//希尔排序

//选取步长分组,对分组的进行直接插入排序,一直到步长为0,因为经过之前的处理已经是大概有序了,在进行直接插入排序很快

//受之前插入代码的影响,有很多对象的构造析构成本消耗,但是思路很清晰!!!

void ShellSort(vector<int> & v,int begin,int end){

    int d = (end-begin+1)/2;

    while(d){

        //    cout<<d<<endl;

        int tempd = d;

        int i = 0,j = 0;

        int tempbegin = begin;

        while(tempd--){

            vector<int> tempivec;

            for(i = tempbegin ; i <= end ; i+=d){     //以d为步长

                tempivec.push_back(v[i]);

            }

            

            InsertionSort(tempivec,0,tempivec.size()-1); //插入排序

            

            

            for(i = tempbegin,j =0 ; i <= end ; i+=d,j++){   //排序后将排序好的部分返回到原vector,第一步 取值分组的逆操作

                //    tempivec.push_back(v[i]);

                v[i] = tempivec[j];

            }

            tempbegin++;

        }

        

        d = d/2;

    }

}



//直接选择排序

void SelectSort(vector<int> & v,int begin,int end){

    int i = 0;

    int k = 0;

    for( ; begin <= end ; begin++){

        int min = v[begin];

        k = begin;              //k记录默认最小位置

        for(i = begin+1;i<=end;i++){

            if(v[i] < min){

                min = v[i];

                k = i;             // k记录最小值的位置,若后面有最小的,更新k的值

            }

        }

        

        if(k != end){

            v[k] = v[begin];

            v[begin] = min;

        }

    }

}

//锦标赛排序



void MakeChamption(vector<int> &v,int begin,int end); //构造一个类似最大堆,选出冠军

void GetChamption(vector<int> &v,int begin,int end);  //将已完成的锦标赛的第一个元素与最后一个元素互换



void ChamptionSort(vector<int> & v,int begin,int end){

    // 堆排序是用来改正锦标赛的缺点的

    //    cout<<"ChampionSort"<<endl;

    while(end > begin){

        GetChamption(v,begin,end);

        //    cout<<v[end]<<endl;

        end--;

    }

}



void GetChamption(vector<int> &v,int begin,int end){

    if(begin >= end)

        return;

    MakeChamption(v,begin,end);

    int temp = v[end];

    v[end] = v[begin];

    v[begin] = temp;

}



void MakeChamption(vector<int> &v,int begin,int end){

    int size = end - begin;

    if(size < 1 )

        return ;                       //如果有1个元素,就不需要再操作了

    

    int parentindex = (end-begin-1)/2+begin;    //index of parent

    while(true){

        //        cout<<"parentindex"<<parentindex<<endl;

        if(parentindex == begin-1)

            return;

        

        int lchildindex = (parentindex - begin) * 2 + 1 + begin;  //index of parent's lchild

        int rchildindex = (parentindex - begin) * 2 + 1 + begin + 1; //index of parent's rchild

        

        int maxchildindex = 0;

        if(rchildindex > end)              //maxchildindex两种情况,若左右孩子存在选较大值得,若右孩子不存在,选左孩子为maxchildindex

            maxchildindex = lchildindex;

        else

            maxchildindex = v[lchildindex] > v[rchildindex] ? lchildindex:rchildindex;

        if(v[maxchildindex] > v[parentindex]){

            int temp = v[parentindex];

            v[parentindex] = v[maxchildindex];

            v[maxchildindex] = temp;

        }

        

        parentindex--;

    }

}



//堆排序

//可以参考《STL源码剖析》 heap部分,172~180,将过程再细分为pop,push部分

void HeapifyIndex(vector<int> &v,int begin,int end,int parentindex); //对v[index]为根的堆进行调整适应

void BuildHeap(vector<int> &v,int begin,int end);

void HeapSort(vector<int> &v,int begin,int end){  //重新实现

    BuildHeap(v,begin,end);

    int tempend = end;

    for( ; tempend > begin;){

        int temp = v[tempend];

        v[tempend] = v[begin];

        v[begin] = temp;

        HeapifyIndex(v,begin,--tempend,begin);

    }

}



void HeapifyIndex(vector<int> &v,int begin,int end,int parentindex){

//     if(parentindex >= end)

//         return;

    int lchildindex = (parentindex - begin) * 2 + 1 + begin;  //index of parent's lchild

    int rchildindex = (parentindex - begin) * 2 + 1 + begin + 1; //index of parent's rchild

    int largeindex = 0;

    if(rchildindex <= end && v[rchildindex] > v[parentindex])

        largeindex = rchildindex;

    else

        largeindex = parentindex;



    if(lchildindex <= end && v[lchildindex] > v[largeindex])

        largeindex = lchildindex;



    if(largeindex != parentindex ){           

        //最大的那个元素如果不是parentindex值,

        //就需要与父节点进行交换,就有可能破坏其子的最大堆性质,因此需要进行递归

        //可参考《算法导论》 p86~90

        int temp = v[largeindex];

        v[largeindex] = v[parentindex];

        v[parentindex] = temp;



        HeapifyIndex(v,begin,end,largeindex);

    }





}

void BuildHeap(vector<int> &v,int begin,int end){           //从最后一个父节点(即end的父)开始往前调整

    int parentindex = (end-begin-1)/2+begin;    //index of parent

    for(;parentindex >= begin ;parentindex--){

        HeapifyIndex(v,begin,end,parentindex);

    }

}









//递归的两路归并

void Merge(vector<int> & v,int begin,int mid,int end){

    vector<int> temp;

    int index1 = begin;

    int index2 = mid+1;

    while(index1 <= mid && index2 <= end){

        if(v[index1] < v[index2]){

            temp.push_back(v[index1]);

            index1++;

        }

        else{

            temp.push_back(v[index2]);

            index2++;

        }

    }

    

    while(index1 <= mid)

        temp.push_back(v[index1++]);

    while(index2 <= end)

        temp.push_back(v[index2++]);

    

    for(int i = 0;i<temp.size();i++){

        v[begin++] = temp[i];

    }

    

}

void MergeSort(vector<int> & v,int begin,int end){

    if(begin < end){

        int mid = (begin+end)/2;

        MergeSort(v,begin,mid);

        MergeSort(v,mid+1,end);

        Merge(v,begin,mid,end);

    }

}



//基数排序

void RadixSort(vector<int> & v,int begin,int end){

    vector< list<int> > listvec;

    listvec.resize(10);

    list<int> resulttemp;

    int i = 0;

    for(i = begin;i<=end;i++)

        resulttemp.push_back(v[i]);

    

    int d = 3;        //d为分配回收的次数,即最大值的位数

    

    int index = 0;       //获取第几位的数,0 为个位,1为十位,2为百位

    list<int>::iterator itres;

    while(d-- > 0){

        itres = resulttemp.begin();

        for(; itres!= resulttemp.end();itres++){           //将所有数以从index的数值(上述规则)分配至相应的桶

            int radix = pow(10,index);

            int numofindex = ((*itres)/ radix)%10;

            listvec[numofindex].push_back(*itres);

        }

        index++;

        

        resulttemp.clear();

        for(i = 0;i<10;i++){                               //依次将桶中的数值回收至list中

            resulttemp.splice(resulttemp.end(),listvec[i]);

            listvec[i].clear();

        }

    }

    

    for(i = begin,itres = resulttemp.begin(); itres != resulttemp.end();itres++,i++){

        v[i] = *itres;

    }

}

 

你可能感兴趣的:(排序算法)