一些排序算法

 

头文件

/*************************
        交换排序
**************************/
//冒泡排序
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;
    }
}

 

posted @ 2015-07-27 16:13  朽木可雕否  阅读(178)  评论(0编辑  收藏  举报