当前位置: 首页 > news >正文

常见排序算法之选择排序

目录

一、选择排序

1.1 什么是选择排序?

1.2 思路

1.2.1 思路一

1.2.2 优化思路

1.3 C语言源码

1.3.1 思路一

1.3.2 优化思路

二、堆排序

2.1 调整算法

2.1.2 向上调整算法

2.1.3 向下调整算法

2.2 建堆排序


一、选择排序

1.1 什么是选择排序?

选择排序是一种简单直观的排序算法。它的基本思想是从未排序的数据中选择最小(或最大)的元素,放到已排序数据的末尾,同时将该元素从未排序部分删除,直到所有元素都排序完成。

具体操作为,首先找到未排序部分的最小元素,并与未排序部分的第一个元素交换位置,这样就完成了一次选择。然后,将接下来未排序部分的第一个元素视为最小,找到最小元素并与未排序部分的第一个元素交换位置,以此类推,直到所有元素都排序完成。

选择排序的时间复杂度为O(n^2),是一种不稳定的排序算法。虽然它的效率相对较低,但由于其简单易实现,可以用于排序小规模的数据集合。然而对于大规模数据集合,选择排序通常不是一个最佳的选择。

1.2 思路

1.2.1 思路一

  1. 遍历第一趟数组,找出数组的最小值,与第一个数据交换
  2. 遍历第二趟数组,继续找出最小值,与第二个数据交换
  3. 重复上述动作

1.2.2 优化思路

  1. 一趟遍历找到最大和最小的元素,分别把他们放到数组的两端
  2. 缩小区间最大最小值包含的区间,找到次大,次小的元素
  3. 以此类推,直到头尾下标重合

该思路可能存在的问题:当maxi的位置与begin重合,则begin先与mini的位置交换,此时max位置的最大值被交换走,导致endmax交换的数值是错误的(图解见下)

1.3 C语言源码

1.3.1 思路一

//交换两个数据
void Swap(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;
}
//选择排序
void SelectSort(int* arr, int n)
{int i = 0;for (i = 0; i < n-1; i++){int min = i;for (int j = i+1; j < n; j++){if (arr[j] < arr[min]){min = j;}}Swap(&arr[i], &arr[min]);}
}

1.3.2 优化思路

//交换两个元素
void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
//插入排序
void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int mini = begin;int maxi = begin;//在区间中找出最小的数和最大的数for (int i = begin + 1; i <= end; i++){if (a[i] > a[maxi]){maxi = i;}if (a[i] < a[mini]){mini = i;}}//最小的数与首交换Swap(&a[begin], &a[mini]);//特殊情况修正if (begin == maxi)				{maxi = mini;}//最大的数与尾交换Swap(&a[end], &a[maxi]);begin++;end--;}
}

二、堆排序

2.1 调整算法

详细图解请见:二叉树的顺序实现-堆-CSDN博客

2.1.2 向上调整算法

void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

2.1.3 向下调整算法

void AdjustDown(int* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){//找出小孩子if (child + 1 < n && a[child + 1] < a[child]){++child;}//交换if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

2.2 建堆排序

请点击:堆排序与TopK问题详解-CSDN博客

相关文章:

  • 内网安全-隧道搭建穿透上线内网穿透-nps自定义上线内网渗透-Linux上线-cs上线Linux主机
  • 微信生态系统介绍
  • Android 待办类应用提醒功能的实现及其问题
  • ⌈ 传知代码 ⌋ 高速公路车辆速度检测软件
  • 全同态加密生态项目盘点:FHE技术的崛起以及应用
  • 编译链接问题
  • 面试的内容
  • java面试(多线程)
  • Canny算子
  • 幼儿园老师投稿渠道
  • 01 一文理解,Prometheus详细介绍
  • Java-Stream流-概述、创建、使用:遍历/匹配、筛选、聚合、映射、归约、排序、提取/组合
  • LeetCode hot100-51-G
  • iOS--工厂设计模式
  • Linux基础知识,配置网卡(七)
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【391天】每日项目总结系列128(2018.03.03)
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • Java基本数据类型之Number
  • Java深入 - 深入理解Java集合
  • Linux Process Manage
  • Linux中的硬链接与软链接
  • miaov-React 最佳入门
  • node入门
  • Octave 入门
  • PHP的类修饰符与访问修饰符
  • PV统计优化设计
  • use Google search engine
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 对象管理器(defineProperty)学习笔记
  • 后端_MYSQL
  • 前言-如何学习区块链
  • 深入 Nginx 之配置篇
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 树莓派 - 使用须知
  • 数据结构java版之冒泡排序及优化
  • 小程序测试方案初探
  • 《天龙八部3D》Unity技术方案揭秘
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ​数据链路层——流量控制可靠传输机制 ​
  • #{}和${}的区别?
  • #HarmonyOS:基础语法
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (转)ObjectiveC 深浅拷贝学习
  • .NET Core 项目指定SDK版本
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .net 发送邮件
  • .NET 某和OA办公系统全局绕过漏洞分析
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .net访问oracle数据库性能问题