数据库入门级之算法【三】

之前我们跟随笔者重温了数据结构中的查询算法和部分排序算法,现在我们继续跟随笔者继续学习一些基本的排序算法。

选择排序

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

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

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

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

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

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

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

总结

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

  1. 待排序的记录数n
  2. 对其稳定性要求
  3. 存储结构
  4. 时间和辅助空间复杂度

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

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

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

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

  1. 快速排序被认为目前基于比较的内部排序中最好的方法。当带排序的关键字随机分布时,快速排序平均时间最短。 不稳定
  2. 堆排序所需要的辅助空间小于快速排序,并且不会出现快速排序可能出现的最坏情况。 但还是比较不稳定
  3. 归并排序,比较稳定,但是归并排序一般不提倡使用,实用性很差,占用的辅助空间肯能个比较大。

 原文链接:http://www.cnblogs.com/couhujia/archive/2011/03/25/1994996.html

【编辑推荐】

  1. 初探数据挖掘中的十大经典算法
  2. 当今世界最受人们重视的十大经典算法
  3. 程序员须知之面试时算法题的解答思路
  4. 数据库入门级之算法【一】
  5. 数据库入门级之算法【二】

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/299638.html<

(0)
运维的头像运维
上一篇2025-05-23 12:10
下一篇 2025-05-23 12:11

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注