常用的排序算法

来源:互联网 发布:阿里云服务器流量计费 编辑:程序博客网 时间:2024/06/05 09:27
/**排序方式插入排序:直接插入排序           Shell排序选择排序:直接选择排序           堆排序交换排序:冒泡排序           快速排序归并排序分配和索引排序:基数排序                 桶式排序*/#include <iostream>using namespace std;//直接插入排序  Arr[]为待排数组,n为数组长度void insertSort(int Arr[],int n){    int i,j;    //从数组的第二位开始进行插入    for(i = 1 ; i < n ; i ++)    {        int temp = Arr[i];//记录当前的值        j = i - 1;//把j赋值成待插入数据的前一位的索引        while(j >= 0 && temp < Arr[j])        {//如果temp小于前面的值,前面的值就向后移位            Arr[j + 1] = Arr[j];            j --;        }        //最后把值赋给该值的适当位置        Arr[j + 1] = temp;    }}//Shell排序/**算法思想:先将待排序列分为若干个子序列,而且要保证子序列中的记录在原始数据中不相邻,且间距相同,分别对这些小子序列进行插入排序;然后减少记录之间的间距,减少小子序列的个数,将原始序列分为更大的更有序的序列分别进行插入排序,重复进行直到最后的间距减少为1*///首先定义一个下面用到的函数  交换数组中的两个元素void Swap(int Arr[],int m,int n){    int temp = Arr[m];    Arr[m] = Arr[n];    Arr[n] = temp;}//子序列的排序void ModInsertSort(int Arr[],int n,int delta){    //cout<<"------"<<Arr[0]<<endl;    int i;    int j;    //从序列的第二个位置开始去插入    //以0为其实的子序列:Arr[0]  Arr[delta]  Arr[delta*2]    for(i = delta ; i < n ; i += delta)    {//如果当前的索引是i   那么应该和前一个进行比较  前一个的索引是j-delta        for(j = i; j > 0 ; j -= delta)        {            if(Arr[j] < Arr[j - delta])                Swap(Arr,j,j-delta);//交换 保证顺序            else break;        }    }}/**实例分析:(只是分解  没有排序  理应在每次分解完成后进行排序)序列     45 34 78 12 34 32 29 64d=4 i=0  45          34    i=1     34          32    i=3        78          29    i=4           12          64d=2 i=0  45    78    34    29d=1       45 34 78 12 34 32 29 64直到d为1*/void ShellSort(int Arr[],int n){    int i;    int delta;    //增量delta每次除以2递减    for(delta = n/2 ; delta > 0 ; delta /= 2)    {        for(i = 0;i < delta ; i ++)        {//把每一次的序列的首元素的地址传入子序列排序  分别对每个子序列进行排序            ModInsertSort(&Arr[i],n - i,delta);        }    }}//直接选择排序//依次选择第i最小的元素放到i位置void SlectSort(int Arr[],int n){    int i;    int j;    int min;    for(i = 0 ; i < n ; i ++)    {        min = i;//把当前的i认为最小        for(j = i + 1; j < n ; j ++)        {//从i+1开始找起            if(Arr[min] > Arr[j])//如果发现更小的记录下标            {                min = j;            }        }        Swap(Arr,i,min);    }}//堆排序的思想是最小堆/**伪码:void HeapSort(int Arr[],int n){    int i;    MinHeap minHeap = MinHeap(Arr,n,n);//建堆    //依次找出剩余记录中的最小元素,即堆顶    for(i = 0 ; i < n ; i++)    {        minHeap.removeMin();    }}*///冒泡排序void BubbleSort(int Arr[],int n){    bool NoSwap;    int i;    int j;    for(i = 0 ; i < n ; i ++)    {        NoSwap = true;        for(j = n - 1; j > i ; j --)        {            if(Arr[j] < Arr[j-1])            {                Swap(Arr,j ,j - 1);                NoSwap = false;            }        }        if(NoSwap) return;    }}//快速排序/**算法思想:1.从待排序列S中任意选择一个记录K作为轴值(pivot)2.将剩余的记录分割成(partition)成左子列L和右子列R3.L中元素都小于或者等于K,R中记录都大于等于K,因此K正好处于正确的位置4.对子序列L和R递归进行快速排序,直到子序列中含有0或者1个元素*///分割函数//快速排序的实现int SelectPivot(int left,int right){    return (left + right)/2;}//int partition(int Arr[],int left,int right){    int l = left;    int r = right;    int temp = Arr[r];    while(l != r)    {        //从开始遍历L子序列 如果子序列中有小于轴值的  不用管 继续向下走        while(Arr[l] <= temp && r > l)        {            l ++;        }        //在L子序列中遇到比轴大的元素        if(l < r)        {            Arr[r] = Arr[l];//把比轴值大的数和交换到轴值后面            r --;        }        //如果在R子序列中遇到比轴值大的数,不用管  继续向下寻找        while(Arr[r] >= temp && r > l)        {            r --;        }        //在R中遇到了比轴值小的数,交换        if(l < r)        {            Arr[l] = Arr[r];//把比轴值小的数换到轴值前面            l ++;        }    }    Arr[l] = temp;    return l;//返回轴值所在的索引}void QuickSort(int Arr[] , int left,int right){    if(left >= right) return;//递归出口L和R中含有0个或者一个元素    int pivot = SelectPivot(left,right);//选择轴值    Swap(Arr,pivot,right);//交换前先把轴值放到数组末尾    pivot = partition(Arr,left,right);//分割后轴值以达到正确的位置    //进行递归    QuickSort(Arr,left,pivot - 1);    QuickSort(Arr,pivot + 1,right);}//归并排序/**算法思想:1.将序列划分为两个子序列2.分别对两个子序列递归进行归并排序3.将这两个已经排好的子序列合并为一个有序序列,即归并过程*///归并到新数组void Merge(int Arr[] ,int temp[] ,int left,int right,int middle){    int i,j,index1,index2;    for(j = left ; j <= right; j ++)    {        temp[j] = Arr[j];    }    index1 = left;    index2 = middle + 1;    i = left;    while(index1 <= middle && index2 <= right)    {        if(temp[index1] <= temp[index2])            Arr[i ++] = temp[index1 ++];        else Arr[i ++] = temp[index2 ++];    }    while(index1 <= middle)        Arr[i ++] = temp[index1 ++];    while(index2 <= right)        Arr[i ++] = temp[index2 ++];}void MergeSort(int Arr[],int temp[],int left,int right){    int middle;    if(left < right)    {        middle = (left + right)/2;        MergeSort(Arr,temp,left,middle);        MergeSort(Arr,temp,middle + 1,right);        Merge(Arr,temp,left,right,middle);    }}//桶式排序/**//桶式排序,Array[]为待排序数组,数组长度为n,所有记录都位于区间[0,max)上template <class Record>void BucketSorter<Record>::Sort(Record Array[], int n,int max){  int* TempArray=new Record[n];//临时数组  int* count=new int[max];//小于或等于i的元素个数  int i;  for (i=0;i<n;i++)  TempArray[i]=Array[i];  //所有计数器初始都为0  for (i=0;i<max;i++)  count[i]=0;  //统计每个取值出现的次数  for (i=0;i<n;i++)count[Array[i]]++;  //统计小于等于i的元素个数  for (i=1;i<max;i++)  count[i]=count[i-1]+count [i];  //按顺序输出有序序列  for (i=n-1;i>0;i--)     Array[--count[TempArray[i]]] = TempArray[i];}*///基数排序/**template <class Record>class RadixSorter:public Sorter<Record,Compare>{public:void Sort(Record Array[],int n,int min,int max);};//数组实现的基数排序,n为数组长度,d为排序码个数,r为基数template <class Record>void RadixSorter<Record>::Sort(Record Array[], int n,int d, int r){Record *TempArray =new Record[n];//辅助排序的临时数组int* count= new int[r];//计数器,Count[i] 存储了第i个桶中的记录数int i,j,k;int Radix=1;//用来取Array[j]的第i位排序码for (i=1; i<=d; i++)// 分别对第i个排序码进行分配{for (j=0; j<r; j++)// 初始计数器均为0count[j] = 0; for (j=0; j<n; j++)// 统计每个桶中的记录数 {k=(Array[j] /Radix)%r;//取Array[j]的第i位排序码count[k]++;//相应计数器加1 }for (j=1; j<r; j++)// 将TempArray中的位置依次分配给r个桶count[j] = count[j-1] + count[j];for (j=n-1; j>=0; j--)// 将所有桶中的记录依次收集到TempArray中{k=(Array[j] /Radix)%r;//取Array[j]的第i位排序码count[k]--;//从第k个桶中取出一个记录,计数器减1TempArray[count[k]] = Array[j];}for (j=0; j<n; j++)// 将临时数组中的内容复制到Array中Array[j] = TempArray[j];Radix*=r;}}*/int main(){    int Arr[7] = {12,45,24,78,14,33,31};    int temp[7]={0};    //insertSort(Arr,7);    //ShellSort(Arr,7);    //SlectSort(Arr,7);    //BubbleSort(Arr,7);    //QuickSort(Arr,0,7);    MergeSort(Arr,temp,0,6);    for(int i = 0 ; i < 7 ; i++)    {        cout<<Arr[i]<<" ";    }    return 0;}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新捷达epc灯亮怎么办 捷达车玻璃升降偏离怎么办 交金中断一个月怎么办 博士拟录取没导师怎么办 保研联系导师后怎么办 特别害怕和导师交流怎么办 面试工资要少了怎么办 一面工资要低了怎么办 家乐卡到期本金还一半怎么办 新三板公司没有资不抵债没钱怎么办 户户通智能卡坏了怎么办 秦岭云无法回看怎么办 身份证在火车站丢了怎么办 到火车站发现身份证丢了怎么办 广电宽带太慢了怎么办 车有后雷达想装前置雷达怎么办 现代朗动油耗大怎么办 雷达线雕头里有水怎么办 上古卷轴5免疫死亡奴役怎么办 dw手表时针不动了怎么办 雷达陶瓷表壳摔坏了怎么办 雷达表盘摔坏了怎么办 雷达测速60超了怎么办 卡西欧手表电池没电了怎么办 审稿人让引用他的文章怎么办 考二建未从事该行业满两年怎么办 2档换3档离合器怎么办 高铁车票丢了怎么办 事业编制调动原单位不同意怎么办 想去铁路上工作怎么办 房产权50年以后怎么办 在香港手机没电怎么办 学校官网登陆忘记密码怎么办 网上申报学校忘记密码怎么办 专转本想换专业怎么办 发生工伤没有平均公资怎么办? 单招过了不想去怎么办 22岁了还想复读怎么办 父母不让我读大专了怎么办 专升本考试失利怎么办 高考复读一年后失败了怎么办?