轻松掌握编程基本算法(三)

移动开发 算法
那么这么多排序算法,到底什么时候用什么样的算法呢?因为不同的排序方法适应不同的应用换进和要求,选择合适的排序方法很重要。

[[121972]]

编程基本算法(一)

编程基本算法(二)

编程基本算法(三) 

选择排序

使用条件:可对比大小的集合。

算法思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

举例编程:int b[10]={77,1,65,13,81,93,10,5,23,17}

  1. //简单选择排序 
  2. void SimpleSelect(int b[10]) 
  3.     int temp; 
  4.     int i; 
  5.     for(i=0;i<9;i++) 
  6.     { 
  7.         for(int j=i+1;j<9;j++) 
  8.         { 
  9.             if(b[i]>b[j]) 
  10.             { 
  11.                 temp=b[i]; 
  12.                 b[i]=b[j]; 
  13.                 b[j]=temp; 
  14.             } 
  15.         } 
  16.     } 
  17.     cout<<"the sort is:"
  18.     for(int i=0;i<10;i++) 
  19.     { 
  20.         cout<<b[i]<<" "
  21.     } 
  22.     cout<<endl; 

性能分析:时间复杂度为O(n^2)

堆排序

使用条件:可对比大小的集合。

算法思想:其实堆排序是简单选择排序的一种进化,它最主要是减少比较的次数。什么是堆?若将序列对应看成一个完全二叉树,完全二叉树中所有非终端节点的值均不大于(或者不小于)其左右孩子节点的值,可以称作为堆。由堆的性质可以知道堆顶是一个最大关键字(或者最小关键字)。在输出堆顶后,使剩下的元素又建成一个堆,然后在输出对顶。如此反复执行,便能得到一个有序序列,这个过程成便是堆排序。

堆排序主要分为两个步骤:

(1)从无序序列建堆。

(2)输出对顶元素,在调成一个新堆。

举例编程:int b[10]={77,1,65,13,81,93,10,5,23,17}

  1. //堆排序 
  2. void HeapSort(int b[10]) 
  3.     void HeapAdjuest(int b[10],int min,int max); 
  4.     void Sawp(int *a,int *b); 
  5.     int i; 
  6.     //因为是完成二叉树,所以从最后一个非叶子节点开始堆转换 
  7.     for(i=9/2;i>=0;i--) 
  8.     { 
  9.         HeapAdjuest(b,i,9); 
  10.     } 
  11.     //拿出堆顶数据在从新堆排序 
  12.     for(i=9;i>0;i--) 
  13.     { 
  14.         Sawp(&b[i],&b[0]); 
  15.         HeapAdjuest(b,0,i-1); 
  16.     } 
  17.  
  18. //堆调整(大顶堆) 
  19. //min 数据需要调整在数组中的开始位置 
  20. //max 数据需要调整在数据中的结束位置 
  21. void HeapAdjuest(int b[10],int min,int max) 
  22.     if(max<=min)return ; 
  23.     int temp; 
  24.     temp=b[min]; 
  25.     int j; 
  26.      
  27.     //延它的孩子节点循环 
  28.     for(j=2*min;j<=max;j*=2) 
  29.     { 
  30.         //选择它的大孩子 
  31.         if(j<max&&b[j]<b[j+1]) 
  32.         { 
  33.             j++; 
  34.         } 
  35.          
  36.         //堆顶大于它的孩子不做处理 
  37.         if(temp>b[j]) 
  38.         { 
  39.             break
  40.         } 
  41.          
  42.         //将大的数替换成小的数 
  43.         b[min]=b[j]; 
  44.         min=j;     
  45.     } 
  46.     b[min]=temp; 
  47.  
  48. //交换函数 
  49. void Sawp(int *a,int *b) 
  50.     int temp; 
  51.     temp=*a; 
  52.     *a=*b; 
  53.     *b=temp; 

性能分析:时间复杂度时间复杂度O(nlogn)

归并算法

又称2路归并算法

使用条件:可对比大小的集合。

算法思想:假设初始序列含有n个记录,则可看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到[n/2]个长度为2或者为1(这里长度为1可能这里序列长度是奇数,那么最后一个序列就落单了,所以长度为1);在两两归并,如此重复,直至得到一个长度为n的有序序列为止。

举例编程:int b[10]={77,1,65,13,81,93,10,5,23,17}

  1. //归并排序 
  2. void MergeSort(int b[10],int d[10],int min,int max) 
  3.     //用与存放中间分区域得到的序列 
  4.     int c[10]; 
  5.     void Merge(int c[10],int d[10],int min,int mid,int max); 
  6.     if(min==max)d[min]=b[min]; 
  7.     else 
  8.     { 
  9.         //平分成两个区域 
  10.         int mid=(min+max)/2; 
  11.         //将这个区域进行归并排序 
  12.         MergeSort(b,c,min,mid); 
  13.         //将这个区域进行归并排序 
  14.         MergeSort(b,c,mid+1,max); 
  15.         //两个区域归并 
  16.         Merge(c,d,min,mid,max); 
  17.     } 
  18.  
  19. //将有序序列d[min-mid]与d[mid+1-max]归并成有序序列c[min-max] 
  20. void Merge(int c[10],int d[10],int min,int mid,int max) 
  21.     int i,j,k; 
  22.     for(i=j=min,k=mid+1;j<=mid&&k<=max;i++) 
  23.     { 
  24.         if(c[j]>c[k]) 
  25.         { 
  26.             d[i]=c[k]; 
  27.             k++; 
  28.         } 
  29.         else 
  30.         { 
  31.             d[i]=c[j]; 
  32.             j++; 
  33.         } 
  34.     } 
  35.     if(j<=mid) 
  36.     { 
  37.         for(;j<=mid;j++,i++) 
  38.         { 
  39.             d[i]=c[j]; 
  40.         } 
  41.     } 
  42.     if(k<=max) 
  43.     { 
  44.          for(;k<=max;k++,i++) 
  45.         { 
  46.             d[i]=c[k]; 
  47.         } 
  48.     } 

性能分析:时间复杂度O(nlogn)

总结

那么这么多排序算法,到底什么时候用什么样的算法呢?

因为不同的排序方法适应不同的应用换进和要求,选择合适的排序方法考虑以下因素:

  • 待排序的记录数n

  • 对其稳定性要求

  • 存储结构

  • 时间和辅助空间复杂度

(1)如果n比较小(例如n<=50),可采用直接插入排序或者简单选择排序。

(2)如果序列初始状态基本有序,则可选用直接插入排序,冒泡排序。

(3)如果n比价大,则可采用时间复杂度为O(nlogn)的算法:快速排序,堆排序,归并排序。

快速排序被认为目前基于比较的内部排序中最好的方法。当带排序的关键字随机分布时,快速排序平均时间最短。 不稳定

堆排序所需要的辅助空间小于快速排序,并且不会出现快速排序可能出现的最坏情况。 但还是比较不稳定

归并排序,比较稳定,但是归并排序一般不提倡使用,实用性很差,占用的辅助空间肯能个比较大。

责任编辑:闫佳明 来源: cnblogs
相关推荐

2014-10-30 16:12:55

编程技术算法

2014-10-30 16:34:28

编程技术算法

2023-07-06 08:31:50

Python对象编程

2023-12-11 18:18:24

Python编程线程

2024-04-10 08:59:39

SpringAOP业务

2022-11-06 21:50:59

Python编程函数定义

2010-01-06 17:51:26

Linux关机命令

2023-08-04 09:43:16

Socket编程Python

2023-05-10 07:42:26

Java多线程编程

2009-01-18 15:14:00

数据仓库开发OLTP

2009-11-12 10:32:47

ADO.NET技术

2010-01-04 17:35:32

Silverlight

2009-12-16 14:26:19

Linux VMwar

2023-09-13 08:00:00

MLOps数据科学

2012-07-17 10:54:49

AJAX

2009-10-12 13:18:55

RHEL 4内核

2023-07-28 08:23:05

选择器Java NIO

2009-12-10 11:02:44

PHP函数eval()

2024-02-27 08:22:56

2009-11-17 17:38:37

PHP Session
点赞
收藏

51CTO技术栈公众号