服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - c++深入浅出讲解堆排序和堆

c++深入浅出讲解堆排序和堆

2022-11-01 15:26YR_T C/C++

在c++里有很多排序方法,比如相对简单的冒泡排序、选择排序、插入排序,还有 STL里的sort函数 手写快排 归并排序等,还有就是堆排序,这次主要说堆排序和堆

堆是什么

堆是一种特殊的完全二叉树

如果你是初学者,你的表情一定是这样的

别想复杂

首先,你一定见过这种图

c++深入浅出讲解堆排序和堆

咱们暂时不管数字

这就是一个堆

堆又分为最大堆和最小堆

最大堆

看这张图

c++深入浅出讲解堆排序和堆

上面的节点的数都比下面的节点的数大,最上面的数是最大的,这就叫最大堆  

最小堆

还是一样的数,看这张图

c++深入浅出讲解堆排序和堆

这是一个最小堆,同最大堆,最上面的节点的数最小,上面的节点的数比下面的节点的数大

怎么样,是不是很简单?

 

堆排序

堆排序的基本思想是利用堆,使在排序中比较的次数明显减少使速度更快

堆排序的时间复杂度为O(n*log(n)), 非稳定排序,原地排序(空间复杂度O(1))。

堆排序的关键在于建堆和调整堆,下面简单介绍一下建堆的过程:

可以用STL下的

make_heap()

具体步骤:

第1趟将索引0至n-1处的全部数据建大顶(或小顶)堆,就可以选出这组数据的最大值(或最小值)。将该堆的根节点与这组数据的最后一个节点交换,就使的这组数据中最大(最小)值排在了最后。

第2趟将索引0至n-2处的全部数据建大顶(或小顶)堆,就可以选出这组数据的最大值(或最小值)。将该堆的根节点与这组数据的倒数第二个节点交换,就使的这组数据中最大(最小)值排在了倒数第2位。

第k趟将索引0至n-k处的全部数据建最大(或最小)堆,就可以选出这组数据的最大值(或最小值)。将该堆的根节点与这组数据的倒数第k个节点交换,就使的这组数据中最大(最小)值排在了倒数第k位。

其实整个堆排序过程中, 我们只需重复做两件事:

建堆(初始化+调整堆, 时间复杂度为O(n));

拿堆的根节点和最后一个节点交换(siftdown, 时间复杂度为O(n*log n) ).

因而堆排序整体的时间复杂度为O(n*log n)

没看懂可以看看这个图

c++深入浅出讲解堆排序和堆

 

最终代码

#include <iostream>
#include <stdlib.h>
using namespace std;

/*******************************************/
/*  堆排序
/******************************************/

void swap(int &a, int &b)  //位置互换函数
{
	int temp = a;
	a = b;
	b = temp;
}


void Heap(int array[], int length, int index)  //堆排序算法(大顶堆)
{
	int left = 2 * index + 1;  //左节点数组下标
	int right = 2 * index + 2;  //右节点数组下标
	int max = index;  //index是父节点

	if (left < length && array[left] > array[max])  //左节点与父节点比较
	{
		max = left;
	}
	
	if (right < length && array[right] > array[max])  //右节点与父节点比较
	{
		max = right;
	}

	if (array[index] != array[max])
	{
		swap(array[index], array[max]);
		Heap(array, length, max);  //递归调用
	}
}


void HeapSort(int array[], int size)  //堆排序函数
{
	for (int i = size / 2 - 1; i >= 0; i--)  // 创建一个堆
	{
		Heap(array, size, i);
	}

	for (int i = size - 1; i >= 1; i--)
	{
		swap(array[0], array[i]);  //将array[0]的最大值放到array[i]的位置上,最大值往后靠
		Heap(array, i, 0);  //调用堆排序算法进行比较
	}
}


int main(void)  //主程序
{
	const int n = 6;  //数组元素的数量
	int array[n];
	cout << "请输入6个整数:" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> array[i];
	}

	cout << endl;  //换行

	HeapSort(array, n);  // 调用HeapSort函数  进行比较

	cout << "由小到大的顺序排列后:" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << "Array" << "[" << i << "]" << " = " << array[i] << endl;
	}

	cout << endl << endl;  //换行

	system("pause");  //调试时,黑窗口不会闪退,一直保持
	return 0;
}

 

关于堆

C++中堆的应用:make_heap, pop_heap, push_heap, sort_heap

函数说明: make_heap将[start, end)范围进行堆排序,默认使用less, 即最大元素放在第一个。

pop_heap将front(即第一个最大元素)移动到end的前部,同时将剩下的元素重新构造成(堆排序)一个新的heap。

push_heap对刚插入的(尾部)元素做堆排序。

sort_heap将一个堆做排序,最终成为一个有序的系列,可以看到sort_heap时,必须先是一个堆(两个特性:1、最大元素在第一个 2、添加或者删除元素以对数时间),因此必须先做一次make_heap.

到此这篇关于c++深入浅出讲解堆排序和堆的文章就介绍到这了,更多相关c++ 堆排序内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/m0_64036070/article/details/123770678

延伸 · 阅读

精彩推荐
  • C/C++C语言实现桶排序的方法示例

    C语言实现桶排序的方法示例

    这篇文章主要介绍了C语言实现桶排序的方法,简单描述了桶排序的概念、原理并结合实例形式分析了C语言实现桶排序算法的具体操作技巧,需要的朋友可以参...

    cjc雪狼10702021-06-11
  • C/C++关于Visual Studio无法打开源文件"stdio.h"问题

    关于Visual Studio无法打开源文件"stdio.h"问题

    这篇文章主要介绍了关于Visual Studio无法打开源文件"stdio.h"问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可...

    故丨是11812021-10-29
  • C/C++C++中指向结构体变量的指针

    C++中指向结构体变量的指针

    结构体变量的指针就是该变来那个所占据的内存段的起始地址。可以设一个指针变量,来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地...

    C++教程网9702021-01-07
  • C/C++clion最新激活码+汉化的步骤详解(亲测可用激活到2089)

    clion最新激活码+汉化的步骤详解(亲测可用激活到2089)

    这篇文章主要介绍了clion最新版下载安装+破解+汉化的步骤详解,本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的...

    贾继康11612021-10-07
  • C/C++C++单例模式应用实例

    C++单例模式应用实例

    这篇文章主要介绍了C++单例模式应用实例,详细讲述了单例模式的原理与结构,及相关的打印机应用实例,需要的朋友可以参考下...

    C++教程网11362021-02-05
  • C/C++C++ Virtual关键字的具体使用

    C++ Virtual关键字的具体使用

    这篇文章主要介绍了C++ Virtual关键字的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    送外卖转行计算机8252021-09-30
  • C/C++C++静态成员函数和this指针详解

    C++静态成员函数和this指针详解

    这篇文章主要为大家介绍了C++静态成员函数和this指针,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    c语言宇8352022-08-01
  • C/C++C++ 使用new与delete需注意的原则

    C++ 使用new与delete需注意的原则

    这篇文章主要介绍了C++ 使用new与delete需注意的原则,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下...

    Dabelv11192021-09-22