zoukankan      html  css  js  c++  java
  • (C/C++学习)9.C/C++优化排序

    说明: 常见的排序算法都是比较排序,非比较排序包括计数排序、桶排序和基数排序,非比较排序对数据有要求,因为数据本身包含了定位特征,所有才能不通过比较来确定元素的位置。比较排序的时间复杂度通常为O(n2)或者O(nlogn),比较排序的时间复杂度下界就是O(nlogn),而非比较排序的时间复杂度可以达到O(n),但是都需要额外的空间开销。本文将介绍的是各种比较排序算法:

    一. 各种排序算法的比较

    二. 未优化的冒泡选择排序法

    1.选择排序法

      1 void sortlist1(int *arr,int n)
      2 {
      3     for(int i = 0;i < n-1;i++)
      4     {
      5         for(int j = i+1;j < n;j++)
      6         {
      7             if(arr[i] > arr[j])
      8             {
      9                 arr[i] ^= arr[j];
     10                 arr[j] ^= arr[i];
     11                 arr[i] ^= arr[j];
     12             }
     13         }
     14     }
     15 }

    2.冒泡排序法

      1 void sortlist2(int *arr,int n)
      2 {
      3     for(int i = 0;i < n-1;i++)
      4     {
      5         for(int j = 0;j < n-1-i;j++)
      6         {
      7             if(arr[j] > arr[j+1])
      8             {
      9                 arr[j]   ^= arr[j+1];
     10                 arr[j+1] ^= arr[j];
     11                 arr[j]   ^= arr[j+1];
     12             }
     13         }
     14     }
     15 }

    三.优化冒泡选择两种排序方法

    1.选择排序法的优化(以从小到大的排列顺序为例)

    从上面的代码可知,选择排序法的思想是让第 i(i 从0开始) 个元素分别与其后面的每个元素进行比较,当比较结果为大于时,就进行交换,这样比较一轮下来,第i个元素成了此轮比较中的最小元素,再继续比较完所有轮,就实现了数组从小到大的排列。这样的排列使得选择排序法的交换次数过于多,降低了排序效率。所以,对选择排序法的优化方案就是:比而不换,记录下标!

      1 void sortlist(int *p,int n)
      2 {
      3     for(int i = 0;i<n;i++)
      4     {
      5         int idx = i;
      6         for(int j = i+1;j<n;j++)
      7         {
      8             if(p[idx] > p[j])
      9                 idx = j;
     10         }
     11         if(idx != i)
     12         {
     13             p[idx] ^= p[i];
     14             p[i] ^= p[idx];
     15             p[idx] ^= p[i];
     16         }
     17     }
     18 }

    如上代码,每次内重循环之后,idx记录本次循环中比较的最小值或最大值(此处为最小值),若idx != i,则说明 i 并不是这次比较的最大或最小值,则进行交换,结束本次循环。

    2.冒泡排序法优化(以从小到大为例)

    冒泡排序法的思想是每轮用第 j(j从0开始) 个元素与第 j+1个元素进行比较,如果大于则交换;这样一轮下来,最大的元素就像冒泡一样到了最后,这样继续比较完所有轮,就实现了冒泡从小到大排序。由此可见,对于冒泡排序法,当某一轮中没有发生过元素的交换时,则表明整个元素序列已经有序了,从而不需要在比较下去。因此,冒泡排序的优化方案为:序而不排。

      1 void sortlist2(int *p,int n)
      2 {
      3     for(int i = 0;i<n;i++)
      4     {
      5         int flag = 0;
      6         for(int j = 0;j<n-1-i;j++)
      7         {
      8 
      9             if(p[j] > p[j+1])
     10             {
     11                 p[j] ^= p[j+1];
     12                 p[j+1] ^= p[j];
     13                 p[j] ^= p[j+1];
     14                 flag = 1;
     15             }
     16         }
     17         if(flag == 0)
     18             break;
     19     }
     20 }

    如果在一个内循环之内,都为有序排列,即没发生过交换事件,则标志flag为0,直接退出循环。

    四. 快速排序

    排序思想:对一组元素,选取第一个元素为比较基数,然后其他元素与他进行比较,比它大的放右边,比它小的放左边,一轮完成,该元素左边都是比它自身小的,右边都是比它大的;然后分别对刚才基数左边和右边的元素重复上述操作,直至排序完成。

      1 void sortlist3(int *p,int low,int high)
      2 {
      3     if(low < high)
      4         //判断元素是否大于1,至少2个元素才排序
      5         int l = low;
      6         int h = high;
      7         int middle = p[low ];
      8          //此处只能用p[low],不能用p[0],因为后面递归要用到
      9         while(l < h)
     10         {
     11             while(p[h] >= middle && l<h)
     12                 h--;
     13             p[l] = p[h];
     14             while(p[l] <= middle && l<h)
     15                 l++;
     16             p[h] = p[l];
     17         }
     18         p[h] = middle;
     19         sortlist3(p,low,h-1);
     20         sortlist3(p,h+1,high);
     21     }
     22 }

    其中 p 为数组名,low为数组起始地址 0,high 为数组的元素个数减1。

    五.插入排序法

     1 void insertsort(int arr[],int length,int beg = 0,int step = 1) {
     2     for(int i = beg+step; i<length; i+=step) {
     3         if(arr[i] < arr[i-step]) {
     4             int temparr = arr[i];
     5             int temp = i;
     6             while(temp-step>=beg && temparr<arr[temp-step]) {
     7                 arr[temp] = arr[temp-step];
     8                 temp = temp - step;
     9             }
    10             arr[temp] = temparr;
    11         }
    12     }
    13 }

    六.希尔排序法

     1 void shellsort(int arr[],int length) {
     2     cout<<"Shellsort the array:      ";
     3     int increment = length/3+1;
     4     int flag = 0;
     5     while(increment>=1) {
     6         if(increment == 1)
     7             flag = 1;
     8         for(int i = 0; i<increment; i+=increment)
     9             insertsort(arr,length,i,increment);          //插入排序      
    10         if(flag == 1)
    11             break;
    12         increment = increment/3+1;
    13     }
    14 }

    七. 归并排序法

     1 /*合并两个有序数组*/
     2 void unionarray(int arr[],int beg,int mid,int end,int*p) {
     3     int temp = mid+1;
     4     int begg = beg;
     5     for(int i = 0;i<end-beg+1;i++) {
     6         if(begg > mid)
     7             p[i] = arr[temp++];
     8         else if(temp>end)
     9             p[i] = arr[begg++];
    10         else {
    11             if(arr[begg]>arr[temp])
    12                 p[i] = arr[temp++];
    13             else
    14                 p[i] = arr[begg++];    
    15         }               
    16     }
    17     for(int i = beg;i<=end;i++)
    18         arr[i] = p[i-beg];
    19 }
    20 /*归并排序*/
    21 void GuiBingsort(int arr[],int beg,int end,int *p) {
    22     if(beg >= end)
    23         return ;
    24     int mid = (beg+end)/2;
    25     GuiBingsort(arr,beg,mid,p);
    26     GuiBingsort(arr,mid+1,end,p);
    27     unionarray(arr,beg,mid,end,p);
    28 }

    八. 堆排序

     1 /*交换数组两个元素*/
     2 void swap(int arr[],int a,int b) {
     3     int temp = arr[a];
     4     arr[a] = arr[b];
     5     arr[b] = temp;
     6 }
     7 /*大顶堆维护*/
     8 void heapAdjust(int arr[],int pos,int _size) {
     9     int max = pos;
    10     int lchild = pos*2+1;
    11     int rchild = pos*2+2;
    12     if(lchild<_size && arr[lchild]>arr[max])
    13         max = lchild;
    14     if(rchild<_size && arr[rchild]>arr[max])
    15         max = rchild;
    16     if(pos != max) {
    17         swap(arr,pos,max);
    18         heapAdjust(arr,max,_size);
    19     }        
    20 }
    21 /*堆排序主程序*/
    22 void heapsort(int arr[],int _size) {
    23     for(int i = _size/2-1;i>=0;i--)
    24         heapAdjust(arr,i,_size);
    25     for(int i = _size-1;i>0;i--) {
    26         swap(arr,i,0);
    27         heapAdjust(arr,0,i);
    28     }    
    29 }
  • 相关阅读:
    mysql decimal(10,2)对应java类型
    idea maven 配置spring boot dev-tools热部署
    在CentOS 8上安装Java 11(OpenJDK 11)和Java 8(OpenJDK 8)的方法
    关于mybatis-plus中Service和Mapper的分析
    Springboot测试类之@RunWith注解
    Get bit field from buffer as an integer / Set bit field in buffer from an integer
    A generic doubly linked list implementation
    Array helper
    Base64 Encoding/Decoding
    ffmpeg color_table[]
  • 原文地址:https://www.cnblogs.com/tuihou/p/9753851.html
Copyright © 2011-2022 走看看