简单选择排序

排序策略

在待排序的数据中选择最小值

排序过程

以集合{76,38,85,97,76,13,27,49}中数据为例,执行排序
①第一趟,在 0~n 找出最小的数

②第二趟,在 1~n 找出最小的数

共执行n-1趟,则直至排序完成

实现代码
/*** 简单选择排序* @param list 需要排序的行列* @return 排序的结果*/public static int[] selSort(int[] list) {//最小值索引int index = 0;//交换中间值int mid = 0;for(int i=0; i<list.length-1; i++) {index = i;for(int j=i; j<list.length-1; j++) {if(list[j+1] < list[index]) {index = j+1;}    }mid = list[i];list[i] = list[index];list[index] = mid;} return list;}

测试结果

时间及空间复杂度

①时间
每一趟进行比较的数目都会递减1,且需交换一次(即赋值三次)
则:最后一趟排序需赋值3次,比较1次,即4
第一趟排序需赋值3比较n-2次,即n+1
则T(n) ≈ 4+5+…+n+1 = (n+1)(n+2)/2 - 6

即时间复杂度为:T(n) = n2

②空间
S(n) = O(1)

③稳定性
不稳定,由于每次只是将最小的值与第i位值进行交换,有可能会使相对位置发生变化

适用范围

①n较小时

②在n个待排序的数据中选择前k(k<<n)个最小值时

堆排序

堆的定义

n 元素的序列 { k1, k2 ,…… , kn },满足:
①ki >= k2i
②ki >= k2i+1

该结构类似于一棵完全二叉树,父结点值大于其孩子的值:

排序策略

根据堆的特性,即根结点为值最大的结点,取出根结点,不断的调整堆结构,直至将堆清空,将取得的根结点按倒叙排列,即最终结果

排序过程

以集合{49, 38, 65, 97, 76, 13, 27, 49}中数据为例,执行一趟冒泡排序

先根据序列中的数据构造堆结构
构造堆的时候,必须从底层(倒数第二层)向上进行构造,这样才可成功将较大结点交换到每个子树的根节点
设从第i个结点进行,在该集合中初始 i=8/2=4

①从第4个结点判断堆结构是否需要调整:可以发现此时97大于其子结点,所以不需调整

②从第3个结点判断堆结构是否需要调整:可以发现此时65大于其子结点,所以不需调整

③从第2个结点判断堆结构是否需要调整:可以发现此时38小于于其子结点,所以需要调整:
即将该结点与其较大的一个子节点进行交换


此时发现该结点38依旧小于其子结点,所以仍旧需要交换

③从第1个结点判断堆结构是否需要调整:可以发现此时49小于其子结点,所以需要调整:
即将该结点与其较大的一个子节点进行交换,然后还需再次和子结点交换一次

取出堆的根结点(堆中最大的结点),再调整堆结构
①取出根结点97,将其与最后一个结点进行交换,脱离堆,再调整堆结构

②取出根结点76,将其与倒数第二个结点进行交换,脱离堆,再调整堆结构

直至n-1个结点从堆结构中提取出来,则排序完成

实现代码

调整堆结构函数,此处需要注意,所数据从索引为0开始,则结点 i 左孩子为 2*i+1

/*** 根据堆的特征调整堆的结构* @param list 堆中数据* @param i 起始位置* @param j 结束位置*/private static void adjustHeap(int[] list, int i, int j) {//定位左孩子(由于索引从0开始)int child = 2*i+1;//对起始(当前子树的根)做存储int root = list[i];//若当前结点有孩子,调整结构使得根结点最大while(child <= j) {//判断左右孩子中最大的孩子(前提存在右孩子)if(child+1 <= j && list[child] < list[child+1]) {child++;}if(list[child] > root) {//若孩子大于父亲,进行交换list[i] = list[child];list[child] = root;//此处由于父子结点进行交换,可能交换后的父结点在子树中仍然小于其子节点//所以因再次循环并判断是否要继续进行交换 i = child;child = 2*i;}else {//若孩子小于父亲,说明当前堆平衡,直接跳出循环break;}}}

主要排序函数:

/*** 堆排序* @param list 需要排序的行列* @return 排序后的结果*/public static int[] heaSort(int[] list) {//先按照原始数据从倒数第二层构建堆,保证堆的平衡System.out.println("构建堆:");int begin = (list.length-1)/2;for(int i = begin; i >= 0; i--) {adjustHeap(list, i, list.length-1);System.out.println(Arrays.toString(list));}//中间值int mid = 0;//共执行n-1趟System.out.println("调整堆:");for(int j = list.length-1; j > 0; j--) {//将最大值从堆中取出,放于数列结尾mid = list[0];list[0] = list[j];list[j] = mid;//调整堆结构adjustHeap(list, 0, j-1);System.out.println(Arrays.toString(list));}return list;}

测试结果

时间及空间复杂度

①时间
由于堆结构是一棵平衡二叉树,即调整函数时间复杂度为O(log2n)
而建立堆的过程时间复杂度为O(n)

堆排序的时间=建立堆+(n-1)次调整堆

即时间复杂度为:T(n) = nlog2n

②空间
S(n) = O(1)

③稳定性
不稳定,因为父子比较及交换是在第i个元素和第2i个元素或第2i+1元素之间进行,即原两个相同大小的记录的位置会有变化。

适用范围

①n较大
②选取前k(k<<n)个最大元素时

选择排序(直接选择、堆)相关推荐

  1. 选择排序—简单选择排序(Simple Selection Sort)

    基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...

  2. [转载] python选择排序二元选择_选择排序:简单选择排序(Simple Selection Sort)

    参考链接: Python中选择排序Selection Sort 基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的 ...

  3. C语言实现选择排序——简单选择排序算法

    C语言实现简单选择排序 文章目录 C语言实现简单选择排序 简单选择排序算法 1.交换操作 2.简单选择排序算法实现 项目完整代码 运行效果图 简单选择排序算法 1.交换操作 //交换实现 void s ...

  4. 【排序二】选择排序(选择排序堆排序)

    [排序一]插入排序 一.选择排序 1.基本思想 顾名思义,选择排序就是每次选一个数据放到其应该出现的位置,以升序(降序)为例,首先选最小(最大)的数据放到正确位置,接着再选次小(次大)的数据放到合适的 ...

  5. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  6. 选择排序-直接选择排序

    直接选择排序(Straight Select Sorting) 也是一种简单的排序方法,它的基本思想是: 第一次从R[0]~R[n-1]中选取最小值,与R[0]交换, 第二次从R{1}~R[n-1]中 ...

  7. c语言对n个数选择排序_选择排序法 -- C语言

    算法原理 直接选择排序的基本思想:n个记录的直接选择排序可经过 n-1 趟直接选择排序得到有序结果. 初始状态:无序区为 A[1...n],有序区为空. 第 1 趟排序:在无序区 A[1...n] 中 ...

  8. C++实现各种选择排序(简单选择排序,堆排序)

    简单选择排序: 代码如下: #include <iostream> using namespace std;void SelectSort(int *a, int len) {//数组下标 ...

  9. 20180321选择排序-简单选择排序

    2019独角兽企业重金招聘Python工程师标准>>> 前置知识 selection sort 选择排序的基本思想:从待排序的序列中选出最大值(最小值),交换该元素与待排序序列头部元 ...

  10. 数据结构/排序/选择排序/简单选择排序

    原理 介绍: 原理:每趟排序记录最小记录的索引后交换 类比:猴子搬苞谷,喜欢更大的苞谷.猴子经过1排苞谷,每经过1个苞谷就与心中的苞谷对比,更大就记录当前苞谷的位置,走完这一排苞谷,心中的那个苞谷就是 ...

最新文章

  1. Android防止按钮连续点击
  2. 不到400元,将你的手机变成可编程AI机器人丨英特尔出品
  3. Win7命令行局域网发消息图解
  4. php扩展开发1--添加函数
  5. 南师大632c语言程序设计,单片机c语言学习心得632.docx
  6. FileNotFoundError: [Errno 2] No such file or directory: 'test/条形图03.html'
  7. 日期的前端验证 jquery
  8. 输入一个三位正整数,输出百位数,十位数,个位数
  9. 常系数线性微分方程的直接解法-利用特征方程
  10. 交公粮了,我经常逛的技术网站,你最爱哪个?
  11. Eclipse 插件 在线安装 收集
  12. 如何在在线直播网站源码中,实现视频连麦直播?
  13. 中国范围的经纬度及部分城市经纬度
  14. 拼多多sdk php,学习猿地-【扩展分享】拼多多 API SDK【拼多多开放平台】
  15. 2007年5月12日,地坛书市
  16. 微信小程序时间轴demo_微信小程序时间轴实现方法示例
  17. Mac切换docker镜像源
  18. graylog+kafka+zookeeper(单机测试及源码),graylog设置URL报警方式(五)
  19. C语言的二进制转十进制
  20. 更改服务器网站默认端口,更改服务器默认端口号

热门文章

  1. JSF Spring Hibernate集成示例教程
  2. 【Java】利用Swing实现登录页面
  3. 【Linux】Ubuntu安装命令
  4. python爬虫之路scrapy
  5. vscode创建代码截图_如何在VSCode中创建代码配置文件
  6. 如何在JavaScript中使用apply(?),call(?)和bind(➰)方法
  7. R语言在金融中的运用一
  8. 127_Power PivotPower BI DAX计算订单商品在库时间(延伸订单仓储费用)
  9. ubuntu下源码安装Python
  10. python中的栈及其实现