• 22-数据结构-内部排序-选择排序


    简介:每一趟选择最小或最大的一个,排在前面或后面。主要右简单选择排序和堆排序

    一、简单选择排序

    1.1简介:

            每趟选择最小的,放在前面,一次类推,代码思想:两个循环,外循环是趟数,内循环是选择最小下标,最后进行交换值,达到排序的目的。

            时间复杂度:O(n^{2})

            空间复杂度:O(1)

            稳定性:不稳定,交换时,可能与另一个关键字相同的位置发生改变,

            适用性:顺序表,链表都可以

            比较次数与初始序列无关:基数排序、简单选择排序,折半插入排序

    1.2代码:

    1. #include <stdio.h>
    2. void swap(int *a,int *b)
    3. {
    4. int temp=(*a);
    5. (*a)=(*b);
    6. (*b)=temp;
    7. }
    8. void SelectSort(int *a,int n)
    9. {
    10. int i,j;
    11. for(i=0;i<n-1;i++)//趟数
    12. {
    13. int min=i;
    14. for(j=i+1;j<n;j++)//查找本趟中最小的一个位置,更新min
    15. {
    16. if(a[j]<a[min])
    17. min=j;
    18. }
    19. //如果min跟开始不同,则交换位置
    20. if(min!=i) swap(&a[min],&a[i]);
    21. }
    22. }
    23. int main()
    24. {
    25. int a[6]={5,6,8,9,1,2};
    26. SelectSort(a,6);
    27. PrintSort(a,6);
    28. return 0;
    29. }

    二、堆排序

    1.1简介:

            堆分为大根堆和小根堆。大根堆为:逻辑上,是个二叉树,给一维数组按层次遍历,弄成二叉树,然后大根堆是每个子树的根都比左右孩子大。同理小根堆每个子树的根都比左右孩子小。

    1.1.1.大小根堆堆排序
    1. 堆调整,即从最后一个非叶子结点开始,自下而上,自右而左,以非叶子结点为根,在其树中找最大的,作为根,然后调整,最后调整到整个树的根后,再整体看是否需要再调整,最后所有的根都是其所在树的最大结点为止。
    2. 给最大值沉底。初始化调整完,就给第一个元素和最后一个元素互换,此时给最大值换到了最后面,下次再大根堆调整就不带上这个最大值了,每次调整完,互换后,长度减1个。

    1.1.2.根堆的插入和删除

            插入的新元素要放在表尾,然后再根据大根堆或小根堆原则,进行堆调整即可。

            在堆中删除元素,直接删除,然后用堆尾的元素补到删除位置处,随后再根据大根堆或小根堆原则,进行堆调整即可。

    1.1.3.性能

            时间复杂度:O(nlog_2{n})

            空间复杂度:O(1)

            稳定性:不稳定,可能给后面相同关键字调整到前面,相对位置发生改变

            选择性:遇到选出前多少个元素的,算法选择堆排序最优。

    1.2代码:

    1.2.1.初始化大根堆代码
    1. //整体大根堆初始化
    2. void BulidMaxHeap(int *a,int len)
    3. {
    4. int i;
    5. for(i=len/2;i>0;--i)//从最后一个非叶子结点开始,依次往前遍历,每次遍历的时候进行堆调整
    6. {
    7. HeadAdjust(a,i,len);
    8. }
    9. }
    10. //大根堆调整
    11. void HeadAdjust(int *a,int k,int len)
    12. {
    13. a[0]=a[k];//a[0]存储原来k的值
    14. int i;
    15. for(i=2*k;i<=len;i=i*2)//判断以k为根的两个孩子谁打
    16. {
    17. if(i<len && a[i]<a[i+1])
    18. i++;
    19. //为了防止原a[k]乱跑,拿a[0]进行比较
    20. if(a[0]>=a[i]) break; //让根与孩子比较,如果根大于孩子,则符合大根堆
    21. else//不符合的话
    22. {
    23. a[k]=a[i];//让大的孩子,赋值给根,覆盖掉
    24. k=i; //然后给原根的坐标挪到孩子处,
    25. }
    26. }
    27. a[k]=a[0];//原根的坐标挪到孩子处,进入第二轮循环,i=i*2,新的堆看是否符合大根堆
    28. }
    1.2.2.大根堆排序
    1. void HeadSort(int *a,int len)
    2. {
    3. BulidMaxHeap(a,len);//初始化大根堆
    4. //排序
    5. int i;
    6. for(i=len;i>0;--i)
    7. {
    8. swap(&a[1],&a[i]);
    9. HeadAdjust(a,1,i-1);//交换后最大值沉底,再进行大根堆调整时,不需要计算最后一个了所以长度为i-1
    10. }

    1.3.总代码:
     

    1. #include <stdio.h>
    2. //打印大根堆,从下标1打印,0处为哨兵,存储原二叉树,根的值
    3. void PrintSort(int *a,int n)
    4. {
    5. int i;
    6. for(i=1;i<n;i++)
    7. {
    8. printf("%d ",a[i]);
    9. }
    10. printf("\n");
    11. }
    12. //交换
    13. void swap(int *a,int *b)
    14. {
    15. int temp=(*a);
    16. (*a)=(*b);
    17. (*b)=temp;
    18. }
    19. //堆排序
    20. //整体大根堆初始化
    21. void BulidMaxHeap(int *a,int len)
    22. {
    23. int i;
    24. for(i=len/2;i>0;--i)//从最后一个非叶子结点开始,依次往前遍历,每次遍历的时候进行堆调整
    25. {
    26. HeadAdjust(a,i,len);
    27. }
    28. }
    29. //大根堆调整
    30. void HeadAdjust(int *a,int k,int len)
    31. {
    32. a[0]=a[k];//a[0]存储原来k的值
    33. int i;
    34. for(i=2*k;i<=len;i=i*2)//判断以k为根的两个孩子谁打
    35. {
    36. if(i<len && a[i]<a[i+1])
    37. i++;
    38. //为了防止原a[k]乱跑,拿a[0]进行比较
    39. if(a[0]>=a[i]) break; //让根与孩子比较,如果根大于孩子,则符合大根堆
    40. else//不符合的话
    41. {
    42. a[k]=a[i];//让大的孩子,赋值给根,覆盖掉
    43. k=i; //然后给原根的坐标挪到孩子处,
    44. }
    45. }
    46. a[k]=a[0];//原根的坐标挪到孩子处,进入第二轮循环,i=i*2,新的堆看是否符合大根堆
    47. }
    48. void HeadSort(int *a,int len)
    49. {
    50. BulidMaxHeap(a,len);//初始化大根堆
    51. //排序
    52. int i;
    53. for(i=len;i>0;--i)
    54. {
    55. swap(&a[1],&a[i]);
    56. HeadAdjust(a,1,i-1);//每次排序排一个,随后以1为根的二叉树,进行堆调整
    57. }
    58. }
    59. int main()
    60. {
    61. int a[9]={0,53,45,87,32,17,65,78,9};
    62. HeadSort(a,8);//数组和有效数据
    63. PrintSort(a,9);//数组和数组长度
    64. return 0;
    65. }

  • 相关阅读:
    11.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏接收网络数据包的操作
    基于 Mixup 数据增强的 LSTM-FCN 时间序列分类学习记录
    详解Python文件: .py、.ipynb、.pyi、.pyc、​.pyd
    《一个程序猿的生命周期》-《发展篇》- 44.再次进军内蒙市场(转型)
    复旦、人大等发布大五人格+MBTI测试 角色扮演AI特质还原率达82.8%
    【多区域电力系统模型】三区域电力系统的LQR和模糊逻辑控制(Matlab代码实现)
    【Linux】题解:Linux环境基础开发工具——Git
    vue的axios是干什么的
    使用dom4j解析XML
    如何有效地开发 Jmix 扩展组件
  • 原文地址:https://blog.csdn.net/m0_59844149/article/details/133895123