排序-选择排序与堆排序

这篇具有很好参考价值的文章主要介绍了排序-选择排序与堆排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、选择排序

思想:
将数组第一个元素作为min,然后进行遍历与其他元素对比,找到比min小的数就进行交换,直到最后一个元素就停止,然后再将第二个元素min,再遍历,以此下去直到最后一个数据
流程图:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
代码实现:

//交换
void Swap(int* a,int* b) {
	int t = *a;
	*a = *b;
	*b = t;
}
//打印
void Print(int* arr, int n) {

	for (int i = 0;i < n; i++)
		printf("%d ", arr[i]);
}
//直接选择排序
void SelectSort(int* arr, int size) {

	for (int i = 0; i < size; i++)
	{
		int min = i;//从第一个开始
		//每次从i+1的位置开始就不会影响到前面的了
		for (int j = i+1; j < size; j++) {
		//比较
			if (arr[min] > arr[j])
				min =j;//记录下标
		}
		Swap(&arr[i], &arr[min]);//交换
	}
 }
int main() {
	int arr[] = { 43152};
SelectSort(arr, sizeof(arr) / sizeof(arr[0]));
Print(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}

运行结果:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
选择排序优化:
我们可以设置一个min和一个max,将小的放到左边,大的放到右边,我们再设置两个控制左右两边下标的变量p,q,当它们相遇时就结束。
流程图:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
特殊情况:max的位置等于p时,我们先交换arr[p]和arr[min],但是max指向p这个位置,但是p这位置的值已经改变了,这时我们就要进行纠正,将max=min,这样才能成功找到原来在p位置的值
如:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
代码实现:

//交换
void Swap(int* a,int* b) {
	int t = *a;
	*a = *b;
	*b = t;
}
//打印
void Print(int* arr, int n) {

	for (int i = 0;i < n; i++)
		printf("%d ", arr[i]);
}
//优化选择排序

void SelectSort1(int* arr, int size) {

	int p = 0, q = size-1;//p指向数组开头,q指向数组最后一个位置
	while (p < q) {//当错过或者相遇就结束
		int min = p, max = p;//迭代位置
		for (int i = p; i <= q; i++)
		{
			if (arr[min] > arr[i])//找到最小值
				min = i;
			if (arr[max] < arr[i])//找到最大值
				max = i;
		}
		Swap(&arr[min], &arr[p]);//交换
		if (max == p)//5 2 3 4 1//判断是否要纠正
			max = min;
		Swap(&arr[max], &arr[q]);//交换
		p++, q--;
	}
}
int main() {
	int arr[] = { 4,3,1,5,2 };
		SelectSort1(arr, sizeof(arr) / sizeof(arr[0]));
	Print(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}

运行结果:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享

二、堆排序

堆:

结构性:用数组表示的完全二叉树;
有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)
“最大堆(MaxHeap)”,也称“大顶堆”,即最大值所有父亲大于等于孩子
“最小堆(MinHeap)”,也称“小顶堆”,即最小值所有父亲小于等于孩子

小堆:堆顶数据是最小的,并且所有节点都小于左右子树
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享

大堆:堆顶数据是最大的 ,并且所有节点都大于左右子树
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
用堆来实现排序:
(1)使用向下调整算法:
前提:左右子树必须是小堆或者大堆
作用:建堆
如:
左右子树对比选择,再与根比较
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
(2)建堆
当我们要实现升序时,通过向下调整法要建大堆
建的过程:因为使完全二叉树,我们可以从最后非叶点节点开始建,直到没有节点就结束。
如:
建大堆
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
找左右子树位置:

树的左子树的下标等于根的下标*2+1,的下标等于根的下标 *2+2

建完后,我们可以将最后一个元素和第一个元素交换,然后再做向下调整即可不用重新建堆了,再让第一个元素和倒数第二个元素交换,以此类推…
为什么不建小堆呢?如果建小堆的话,用第一个根(最小值)就是数组的第一个元素了,我们不能动它,那么再让数组的第二元素重新做根,但是这样的话顺序就会被打破,又要重新建堆了,那样时间复杂度会提高(如何实现降序的话可以建小堆)

代码实现:

//交换
void Swap(int* a,int* b) {
	int t = *a;
	*a = *b;
	*b = t;
}
//打印
void Print(int* arr, int n) {

	for (int i = 0;i < n; i++)
		printf("%d ", arr[i]);
}
//向下调整  大堆
void AdjustDwon(int *arr,int p,int size) {
	int q = p;//节点位置
	int z = q * 2 + 1;//节点左子树,z+1就是右子树的位置了
	while (z<size) {//当z大于数组长度时就说明该节点不存在左右子树
	//判断左右子树大小,后面是判断是否有右子树
		if (arr[z] <arr[z + 1]&&z+1<size)
			z += 1;
		if (arr[z] > arr[q]) {//判断是否比根大
			Swap(&arr[z], &arr[q]);
			q = z;
			z = q * 2 + 1;//迭代
		}
		else
			break;
	}
}
void  HeapSort(int* arr,  int size) {
	//建堆,size-1-1就是除2(求子树公式反过来用,最后减一是因为我们求的是下标)
	for (int i = (size - 1 - 1) / 2; i >= 0; i--) {
		AdjustDwon(arr, i, size);
	}
	int ned = size - 1;
//最后一个下标位置开始,和下标为0的元素交换,一直交换下去,并且交换一次就调整一次
	//当ned==1就证明排好了
	while (ned>0) {
		Swap(&arr[0], &arr[ned]);
		AdjustDwon(arr, 0, ned);//重新调整
		ned--;
	}
}

int main() {
	int arr[] = { 4,3,1,5,2 };
	HeapSort(arr, sizeof(arr)/sizeof(arr[0]));
	Print(arr, sizeof(arr) / sizeof(arr[0]));
return 0}

运行结果:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享

三、时间复杂度

选择排序:
n-1 ,n-2…2,1
是一个等差数列求前n-1项和,粗略来算就是n^2
所以时间复杂度为O(n^2)

堆排序:
建堆:O(n)
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
向下调整的时间复杂度为:
假设树高为 h,树的结点为n,因为n=2^h-1,那么h=log(n-1)(以2为底)
所以为O(logn-1)
我们还要进行n次这个向下调整(当然在进行的过程中n是会变化的)
那么总的次数n+nlogn
所以时间复杂度为O(n
logn)

四、稳定性

稳定性:

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[4],且r[1]在r[4]之前,而在排序后的序列中,r[1]仍在r[4]之前,则称这种排序算法是稳定的;否则称为不稳定的。

选择排序:不稳定
如:
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
堆排序:不稳定
排序-选择排序与堆排序,数据结构,排序算法,算法,数据结构,c语言,开发语言,经验分享
第一个9直接到最后了

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!文章来源地址https://www.toymoban.com/news/detail-756040.html

到了这里,关于排序-选择排序与堆排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构与算法】排序算法:冒泡排序,冒泡排序优化,选择排序、选择排序优化

    目录 一、冒泡排序 1、冒泡排序思想 2、冒泡排序算法的性能分析 代码实现: 二、选择排序 1、选择排序思想 2、选择排序算法的性能分析  代码实现: 1、冒泡排序思想 冒泡排序的基本思想是通过相邻元素之间的比较和交换来逐步将最大(或最小)的元素移到右边(或左边

    2024年01月19日
    浏览(50)
  • 数据结构与算法—插入排序&选择排序

    目录 一、排序的概念 二、插入排序   1、直接插入排序  特性总结: 2、希尔排序 特性总结:  三、选择排序 1、直接选择排序  特性总结: 2、堆排序—排升序(建大堆) 向下调整函数 堆排序函数 特性总结: 代码完整版:   头文件  函数文件  测试文件 排序 :所谓排序,

    2024年01月20日
    浏览(63)
  • 【数据结构与算法】排序算法(选择排序,冒泡排序,插入排序,希尔排序)

    基本概念这了就不浪费时间解释了,这四种都是很简单的排序方式,本专栏后续文章会出归并排序,计数排序,快速排序,堆排序,桶排序等排序算法,今天这篇文章中给出选择排序,冒泡排序,插入排序和希尔排序的实现; 如果发现文章中有错误,还请大家指出来,我会非

    2024年02月15日
    浏览(86)
  • 数据结构算法--2 冒泡排序,选择排序,插入排序

    思想就是将相邻元素两两比较,当一个元素大于右侧相邻元素时,交换他们的位置,小于右侧元素时,位置不变,最终序列中的最大元素,像气泡一样,到了最右侧。 这时冒泡排序第一轮结束,数列最右侧元素9的位置可认为是一个有序区,有序区目前有一个元素. 第二轮排序

    2024年02月13日
    浏览(64)
  • 【数据结构与算法】:选择排序与快速排序

    🔥 个人主页 : Quitecoder 🔥 专栏 :数据结构与算法 我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:腾讯云 欢迎来到排序的第二个部分:选择排序与快速排序! 选择排序是一种简单直观的比较排序算法。该算法的基本思想是在每一轮中选出当前未排序部分的最

    2024年03月17日
    浏览(53)
  • 【数据结构】八大排序之简单选择排序算法

    🦄 个人主页 :修修修也 🎏 所属专栏 :数据结构 ⚙️ 操作环境 : Visual Studio 2022 目录 一.简单选择排序简介及思路 二.简单选择排序的代码实现 三.简单选择排序的优化 四.简单选择排序的时间复杂度分析 结语 简单选择排序算法(Simple Selection Sort) 是一种简单直观的 选择排序算

    2024年02月01日
    浏览(78)
  • 【数据结构】排序算法(一)—>插入排序、希尔排序、选择排序、堆排序

    👀 樊梓慕: 个人主页   🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.直接插入排序 2.希尔排序 3.直接选择排序 4.堆排序 本篇文章博主将介绍排序算法中的插入排序:直接

    2024年02月08日
    浏览(49)
  • 【数据结构】常见排序算法——常见排序介绍、选择排序(直接选择排序、堆排序)交换排序(冒泡排序)

      选择排序是一种简单但不高效的排序算法,其基本思想是从待排序的数据中选择最小(或最大)的元素放到已排序的数据末尾。具体操作步骤如下: (1)找到数据中最小的元素,并把它交换到第一个位置; (2)在剩下未排序的元素中找到最小的元素,并把它交换到已排

    2024年02月04日
    浏览(56)
  • 『初阶数据结构 • C语言』⑤ - 选择排序

    本文内容借鉴一本我非常喜欢的书——《数据结构与算法图解》。学习之余,我决定把这本书精彩的部分摘录出来与大家分享。     目录 写在前面 1.选择排序 2.选择排序实战 3.选择排序的实现 4.选择排序的效率 5.忽略常数 6.大O的作用 7.总结     大 O 是一种能够比较算法效

    2024年02月14日
    浏览(45)
  • 直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序——“数据结构与算法”

    各位CSDN的uu们你们好呀,今天小雅兰的内容是数据结构与算法啦,是排序!!!下面,让我们进入七大排序的世界吧!!! 排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在

    2024年02月15日
    浏览(71)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包