选择排序包括:选择排序,双选择排序以及堆排序。
选择排序的核心是每一趟排序中查找最小值或者最大值的索引,然后与边界的位置进行交换。例如当前待排序的元素值为a[i],设置最小值所对应的索引为minIndex,初始值就为i。这样一次循环后,minIndex的值可能会变,也可能不变,只有当变化的时候我们交换一下即可。下面看一下常见的选择类型的排序。

(1)选择排序

void selectSort(int *a, int n) {for(int i=0; i<n; ++i) {int minIndex = i;//记录最小值所对应的索引  初始值为i//查找最小值所对应的索引for(int j=i+1; j<n; ++j) {if(a[j] < a[minIndex]) minIndex = j;}//最小值索引发生了改变  我们就交换他俩if(i != minIndex) swap(a[i], a[minIndex]);}
}

(2)双选择排序

双选择排序本质上还是选择排序,可以说只是对直接选择排序做了优化。双选择排序每趟循环中同时找到最大值和最小值的索引,最大值和最小值初始的索引为待排序数组的两个边界,当一趟查找结束后,如果有索引发生了变化,就进行交换。

void biSelectSort(int *a, int n) {int left=0, right=n-1;//待排序数组的两个边界//只有当数组中还有两个元素时才需要进行排序  只有一个时数组已经有序while(left < right) {    int minIndex=left, maxIndex=right;//保证最小值一定小于最大值if(a[minIndex] < a[maxIndex]) swap(a[minIndex], a[maxIndex]); //在[left+1, right-1]闭区间中   查找最大值和最小值的索引for(int i=left+1; i<right; ++i) {if(a[i] < a[minIndex) minIndex = i;else if(a[i] > a[maxIndex]) maxIndex = i;}swap(a[left], a[minIndex]);swap(a[right], a[maxIndex]);left ++, right --;//缩小范围}
}

(3)堆排序

堆排序在底层中使用了堆这样的数据结构,堆维护的性质是,若为大根堆,则任意根节点的值大于其左右孩子节点的值。堆同时是一完全二叉树的的逻辑结构,堆很方便的可以使用数组来实现,因此是一种线性的存储结构,方便编程,主要利用到是完全二叉树的性质:

1.若任意节点的索引为j,若其左右孩子都存在,则它们的索引分别是2 * j2*j+1
2.任意节点的父亲节点的索引为j/2,满足这样关系的前提条件是数组下标从1开始,否则若根节点的下标从0开始判断比较麻烦,需要讨论奇偶性。所以在实现的时候我们需要多开辟一个存储空间,因为鼠标下标为0的位置不使用。

下面来看堆排序的简单实现:

void heapSort(int *a, int n) {Heap<int> heap(n);for(int i=0; i<n; ++i) heap.insert(a[i]);for(int i=0; i<n; ++i) a[i] = extractMin();
}

时间复杂度的分析:在heapSort的实现过程中,insert方法中会涉及shitfUp操作,shiftUp操作的时间复杂度为O(logn),外层循环的时间复杂度为O(n),因此第一层总的时间复杂度为O(n * logn), 同样第二层循环,外层循环的时间复杂度为O(n), 内层extractMin()函数会涉及到shiftDown操作, shiftDown操作的时间复杂度为O(logn), 因此总的时间复杂度也为O(n * logn), 所以最终总的时间复杂度任为O(n * logn)。
下面来看小根堆的简单实现:

#include <iostream>
#Include <cassert>
using namespace std;template <typename T>
class Heap{
private:int cnt;//当前堆中的节点个数int capacity;//堆的容量T *data;//存放数据的线性结构void shiftDown(int k) {while(2 * k <= cnt) {int j = 2 * k;//j此时为左孩子节点的索引//有孩子节点存在    并且有孩子节点比左孩子节点还小 j++    if(j  + 1 <= cnt && data[j+1] < data[j])  j ++; if(data[k] <= data[j]) break;//如果根节点比min(data[j], data[j+1])更小,break掉swap(a[k], a[j]);k = j;}}void shiftUp(int k) {while(k>1 && data[k/2] > data[k]) {swap(data[k/2], data[k]);jk /= 2;}}public:Heap(int capacity) {this->cnt = 0;//初始堆中没有节点,初始化为0this->capacity = capacity;//注意这里很重要, data中下标为0位置并不使用,因此需要多开辟一个存储空间data = new T[capacity + 1];}~Heap() {delete [] data;}void insert(int x) {assert(cnt + 1 <= capacity);data[cnt + 1] = x;shiftUp(cnt + 1);cnt ++;}T extractMin() {assert(cnt > 0);T res = data[1];swap(data[1], data[cnt]);cnt --;shiftDown(1);return res;}
};

数据结构:选择类型排序的总结(考研)相关推荐

  1. 数据结构------选择排序

    数据结构------选择排序 原理:参考趣学数据结构 代码: #include<stdio.h> #include<stdlib.h> void simpleSelectSor ...

  2. MySQL数据结构选择的合理性

    MySQL数据结构选择的合理性 从MySQL的角度讲,不得不考虑一个现实的问题的就是磁盘IO.如果我们能够让索引的数据结构尽量减少磁盘I/O操作,所消耗的时间也就越小.可以说,磁盘的I/O操作次数对索 ...

  3. 数据结构-常用的排序算法

    总第123篇 好久不见哈,我终于又更新了,惊不惊喜,意不意外,哈哈哈哈.等之后会专门写一篇文章给大家汇报汇报我最近在忙什么呢,今天这篇还是接着之前的数据结构系列继续,主要讲讲数据结构里面常用的几种排序 ...

  4. 鸿蒙轻内核M核源码分析:数据结构之任务排序链表

    摘要:鸿蒙轻内核的任务排序链表,用于任务延迟到期/超时唤醒等业务场景,是一个非常重要.非常基础的数据结构. 本文会继续给读者介绍鸿蒙轻内核源码中重要的数据结构:任务排序链表TaskSortLinkAt ...

  5. 排序-选择类排序--堆排序简介

    参考:数据结构(严蔚敏) 选择类排序有两个经典算法,一个是之前总结过的直接选择排序,另一个则是今天要讲的堆排序 0.什么是堆 对于Java中的一个数组Array,如果对于其中所有的元素其下标index ...

  6. 一年后再回头看系列之C/C++中的选择法排序、冒泡排序

    文章目录 前言 一.两种排序算法的基本思想 二.具体步骤 1.引入库 2.生成随机数 三.具体代码 前言 转眼大二了,突然感觉比大一还要迷茫(也可能是因为数模竞赛,评优都没有搞好,明年暑假的智能车也一 ...

  7. 数据结构实验之排序八:快速排序

    数据结构实验之排序八:快速排序 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 给定N ...

  8. C语言 冒泡法排序,选择法排序和插入排序

    实例1 冒泡法排序 数组中有N个整数,用冒泡法将它们从小到大(或从大到小)排序. 实例解析: 排序是非常重要且很常用的一种操作,有冒泡排序.选择排序.插入排序.希尔排序.快速排序.堆排序等多种方法.这 ...

  9. Java数据结构之八大排序算法

    目录 一.排序算法的介绍 1.排序算法 2.算法时间的频度 时间频度 3.时间复杂度 4.常见的时间复杂度 5.平均时间复杂度和最坏时间复杂度 6.空间复杂度 二.冒泡排序 1.基本介绍 2.模拟冒泡 ...

  10. [ 数据结构 -- 手撕排序算法第三篇 ] 希尔排序

    手撕排序算法系列之:希尔排序. 从本篇文章开始,我会介绍并分析常见的几种排序,大致包括插入排序,冒泡排序,希尔排序,选择排序,堆排序,快速排序,归并排序等. 大家可以点击此链接阅读其他排序算法:排序算 ...

最新文章

  1. Hibernate二级缓存的使用
  2. Redis 热点 Key 如何发现?又该如何解决?
  3. (转载)Markdown基本语法
  4. angr学习笔记(1)
  5. openstack前世今生
  6. 如何使Mac Docker支持SQL on Linux容器Volume特性
  7. 安川最小巧机器人_2020工博会,安川展品前瞻(机器人篇)
  8. Nhibernate中Unexpected row count的一种解决办法
  9. 基于 Generator 和 Iterator 的惰性列表
  10. (day 25 - 广度优先搜索 )剑指 Offer 32 - II. 从上到下打印二叉树 II
  11. linux用vim编辑后保存显示错误,因为vim编辑文档未保存。再次编辑同一个文件时出现报错的解决...
  12. 解决百度文库复制问题 非VIP也能复制文字
  13. 对大学的规划 计算机专业,对计算机专业的认识及你大学四年的规划与设想
  14. 小米手机微信指纹支付上传服务器吗,小米MIUI支持微信指纹支付吗 小米MIUI微信指纹支付【图文】...
  15. Matlab:成功解决In an assignment A(I)=B,the number of elements in B and I must be the same
  16. (一)ROS中新建机器人模型(urdf格式)并用rviz显示
  17. 怎么样才能彻底消灭猫瘟病毒?
  18. 《被讨厌的勇气》书摘心得之一切烦恼都来自人际关系(2)
  19. 解决Vue history模式下使用嵌套路由打包部署后刷新页面为空白页
  20. 从物理意义上了解PCA

热门文章

  1. Linux基础教程: 4、用户组和用户的创建
  2. 【初学者入门C语言】之习题篇(一)
  3. 怎么去掉微博图片中的水印,照片水印怎么去
  4. odis工程师使用教程_ODIS 教程及工程师通过电脑软件版本改零件号
  5. 使用google earth engine(GEE)提取亚马逊每年森林火灾区域
  6. Unity 制作数字图片字体
  7. 【大数据安全分析】图计算在安全方面的应用思考
  8. 计算机网络——第一章 计算机网络体系结构
  9. 递归实现顺序输出整数
  10. 陈越何欣铭老师数据结构PTA08-图8 How Long Does It Take