zoukankan      html  css  js  c++  java
  • 一些排序算法

    头文件

    /*************************
            交换排序
    **************************/
    //冒泡排序
    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;
        }
    }
  • 相关阅读:
    idea快速生成javaBean快捷键
    2019.10.22 关于java对象的一些理解
    2019.10.21 解决win10电脑qq通话没有声音
    知乎上看到的好的文章
    2019.10.2怎么查看那些ip访问了你的网站
    2019.10.1怎么在服务器上建一个网站
    2019.9.30第一次把自己写的前端东西放在服务器上哈哈
    新手容易犯的错误
    Python3-列表推导式
    Python3-os模块
  • 原文地址:https://www.cnblogs.com/xiumukediao/p/4680437.html
Copyright © 2011-2022 走看看