【数据结构】C语言实现排序算法------堆排序

news/2024/5/19 3:53:56 标签: 算法, 数据结构, 排序算法, 堆排序, c语言

堆排序:利用这种数据结构所设计的一种排序算法

大堆: 根节点值大于子节点的值,对应为升序序列。

小堆: 根节点值小于子节点的值,对应为降序序列。

堆排序实现的两个步骤:

  1. 创建堆
  2. 堆排序

下述例子是进行大堆创建:

  1. 创建大堆:图例
    在这里插入图片描述
    创建步骤:
  1. 寻找最后一个分支的根节点(记为pos)
  2. pos挨个减小,对每个分支,都进行大堆排列。根节点比子节点值大
  3. 终止条件:pos < 0,不再进行大堆创建。
  1. 堆排序:升序
    在这里插入图片描述
    排序步骤:
  1. 堆顶元素和末尾元素值交换
  2. 最大值排在末尾,该值不再做交换
  3. 调整堆结构,满足大堆定义。重复执行步骤1,2,直到达到堆顶位置

C代码实现:

void ShiftDown(int *arr, int left, int right, int pos)
{
	int i = pos;//根节点
	int j = 2 * i + 1 + left;//子节点
	int n = right - left;
	int tmp = arr[i];
	while (j < n)
	{
		if (j + 1 < n && arr[j + 1] > arr[j])//找子节点最大值
			j++;
		if (arr[j] > tmp)//子节点比根节点大
		{
			arr[i] = arr[j];//根节点值等于子节点的值
			i = j;//往下调整
			j = 2 * i + 1;
		}
		else
			break;
	}
	arr[i] = tmp;//循环退出,根节点的值等于最开始的arr[pos]值
}

void HeapSort(int *arr, int left, int right)
{
	int n = right - left;
	int pos = (n - 2) / 2 + left;//寻找最后一个分支的根节点
	while (pos >= 0)//建堆
	{
		ShiftDown(arr, left, right, pos--);
	}

	int end = n;
	while (end >= 2)//排序
	{
		end--;
		Swap(&arr[end], &arr[left]);//交换堆顶和尾部元素
		ShiftDown(arr, left, end, left);
	}
}

堆排序整体步骤:

  1. 建堆:大堆或小堆。先找到最后一个分支的根节点。再对个分支都进行调整。
  2. 排序:堆顶和末尾数据交换,调整堆结构,尾部下标-1。再进行排序。

特性总结:

  1. 时间复杂度:O(N*logN)
  2. 空间复杂度:O(1)
  3. 稳定性:不稳定

http://www.niftyadmin.cn/n/1664544.html

相关文章

node.js 发布订阅模式

//导入内置模块 let EventEmitter require(events); let utilrequire(util); //Man继承EventEmitter util.inherits(Man,EventEmitter); //创建一个函数 function Man(){} //实例化函数 let mannew Man();function findGirl() {console.log(找新的女朋友) } function saveMon…

【Linux】进程控制之程序替换的理解

进程程序替换&#xff1a;替换一个进程&#xff0c;调度运行其它程序。 替换原理&#xff1a;替换的是当前子进程的数据段和代码段产生现象&#xff1a; 子进程PID不发生改变。替换成功之后&#xff0c;执行的是替换之后的程序&#xff0c;输出的内容也和之前的程序无关不再执…

使用Linux Bridge 搭建vxlan 实现 虚拟机跨物理机通信

#实验环境&#xff1a; #本次实验要让192.168.1.3 跨物理节点 ping 通 192.168.1.2 #两台物理机&#xff1a; KVM_1192.168.174.134KVM_2192.168.174.135#在KVM_1主机上操作 #安装KVM相关软件 12345678[rootKVM_1 ~]# yum -y install qemu-kvm libvirt virt-install bridge-u…

【Linux学习笔记】17:Linux中的Shell概述

shell本身的涵义 shell本身是计算机壳层&#xff0c;是指”提供使用者使用界面”的软件(命令解析器)&#xff0c;分为图形界面shell(GUI shell)和命令行式shell(CLI shell)。 在Linux中的涵义 ①shell是一个命令解释器&#xff0c;为用户提供可以向Linux内核发送请求以便运行…

【C++】深入理解类和对象中构造函数

六大默认成员函数中&#xff0c;介绍了构造函数的作用&#xff0c;使用方法。 这份代码中&#xff1a; class Date { public:Date(int year, int month, int day)//构造函数{_year year;_month month;_day day;} private:int _year;int _month;int _day; };void TestClass…

使用Spring Data Redis操作Redis(二)

1. Redis的Pub/Sub命令 Redis的订阅和发布服务有如下图6个命令&#xff0c;下面分别对每个命令做简单说明。 publish: 向指定的channel(频道)发送message(消息) subscribe:订阅指定channel&#xff0c;可以一次订阅多个 psubscribe:订阅指定pattern(模式&#xff0c;具有频道名…

【Linux学习笔记】18:脚本执行方式

在Linux中可以写一些自己要用的脚本&#xff0c;这节学习怎么执行它们。 补充&#xff1a;echo把指定内容输出到屏幕 echo [选项] [输出内容] 选项&#xff1a;-e支持反斜杠支持的字符转换。 这些字符有\a输出警告音&#xff0c;\b退格键&#xff0c;\n换行符&#xff0c;\…

【C++】浅谈static关键字的在C语言和C++的作用

C语言中&#xff1a; 作用一&#xff1a;修饰变量。 变量分为局部变量和全局变量&#xff0c;则用static修饰&#xff0c;也分为静态局部变量和静态全局变量。 静态局部变量&#xff1a;在函数体中使用static修饰变量&#xff0c;可改变生命周期&#xff0c;但不能改变作用域…