【数据结构学习】-堆与堆排序

堆是一种非常有用的数据结构,可用来设计高效的排序算法和优先队列。一个堆是一颗具有如下性质的二叉树:1)它是一颗完全二叉树;2)每个节点都大于等于其任何子节点。

如上图是一个最大堆,我们可以用数组来描述它。根节点在数组位置0,两个孩子在位置1和2。对于位于位置i的节点,其左孩子在2i+1,其右孩子在2i+2,其父节点在(i-1)/2。利用堆进行排序,是堆一个很重要的用途。下面是堆排序的代码:

#include <iostream>
using namespace std;
void adjustHeap(int a[],int size,int index)
{
	int left = index*2+1;		//左子节点在数组中的位置
	int right = index*2+2;		//右子节点在数组中的位置
	int largest = index;
	int temp;
	while(left<size || right<size)		//循环遍历,直到没有子节点为止
	{
		if(left<size && a[left]>a[largest])
		{
			largest = left;
		}
		if(right<size && a[right]>a[largest])
		{
			largest = right;
		}							//找到左右子节点和根节点的最大值
		if(index!=largest)			//如果根节点不是最大值
		{
			temp=a[largest];
			a[largest]=a[index];
			a[index]=temp;			//交换子节点和根节点
			index=largest;			//继续向下遍历,调整堆
			left=index*2+1;
			right=index*2+1;
		}
		else
		{
			break;
		}
	}
}
void buildHeap(int a[],int size)
{
	int begin=size/2-1;		//从该结点往后的值都没有子节点
	for(int i=begin;i>=0;i--)		//建立最大堆
	{
		adjustHeap(a,size,i);
	}
}
void heapSort(int a[],int len)
{
	int size=len;
	int temp;
	buildHeap(a,size);
	while(size>1)
	{
		temp=a[0];
		a[0]=a[size-1];
		a[size-1]=temp;
		size--;
		adjustHeap(a,size,0);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int num[8]={2,8,7,1,3,5,6,4};
	cout<<"排序前的输出顺序为:"<<endl;
	for(int i=0;i<8;i++)
	{
		cout<<num[i]<<"\t";
	}
	heapSort(num,8);
	cout<<endl<<"排序后的输出顺序为:"<<endl;
	for(int i=0;i<8;i++)
	{
		cout<<num[i]<<"\t";
	}
	return 0;
}

输出结果为:

排序前的输出顺序为:

2 8 7 1 3 5 6 4

排序后的输出顺序为:

1 2 3 4 5 6 7 8

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 21:29:31

【数据结构学习】-堆与堆排序的相关文章

数据结构学习——堆

1 基本介绍 堆数据结构是一种数组对象,它可以被视为一颗完全二叉树.堆的访问可以通过三个函数来进行即, parent(i) return floor(i/2); left(i) return 2i; right(i) return 2i + 1; left操作可以通过一步左移操作完成,right操作可以通过左移并在地位+1实现,parent操作则可以通过把i右移一位得到.在实现中通常会使用宏或者内联函数来实现这三个操作. 二叉堆有两种,最大堆和最小堆.对于最大堆有 A[i] >= A[left(

数据结构学习(十一)、堆排序

基本思想:将待排序的序列构成一个大顶堆.此时,最大的值就是堆顶,将它一走,并将余下的序列重新构造成一个堆.如此反复. void HeapSort(SqLsit *L) { int i; for(i=L->length/2;i>0;i--) HeapAjust(L,i,L->length); for(i=L->lengt;i>1;i--){ swap(L,1,i); HeapAjust(L,1,i-1); } } /* 除L->data[s]外满足堆的定义 */ /* 调

[数据结构学习备忘录]堆及其堆排序

[数据结构学习备忘录] 堆 一种数据结构,物理存储方式:数组 逻辑存储方式:近似于完全二叉树,假定i为堆元素的序数[Index],那么i/2就是该元素的左子树,(i/2 + 1)就是该元素的右子树,分为两种堆:大根堆.小根堆:这两种堆的区别是:大根堆的根节点元素的值比左右子树的值都要大,小根堆则相反. 可用这种数据结构进行排序,称为堆排序. 与该数据结构相关的关键算法: ①   MaxHeaplfy 当堆的元素顺序出现错误时的调整函数 ②   BulidMax[min]Heap 建立大[小]根堆

数据结构与算法之美-堆和堆排序

堆和堆排序 如何理解堆 堆是一种特殊的树,只要满足以下两点,这个树就是一个堆. ①完全二叉树,完全二叉树要求除了最后一层,其他层的节点个数都是满的,最后一层的节点都靠左排列. ②树中每一个结点的值都必须大于等于(或小于等于)其子树中每个节点的值.大于等于的情况称为大顶堆,小于等于的情况称为小顶堆. 如何实现堆 如何存储一个堆 完全二叉树适合用数组来存储,因为数组中对于下标从1开始的情况,下标为i的节点的左子节点就是下标为i*2的节点,右子节点就是i下标为i*2+1的节点,其父节点时下标为i/2的

白话经典算法系列之七 堆与堆排序

堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)不论什么一个子节点的键值. 2.每一个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于不论什么一个子节点的键值时为最大堆.当父结点的键值总是小于或等于不论什么一个子节点的键值时为最小堆.下图展示一个最小堆

数据结构学习之二叉排序树

介绍:二叉排序树是以一定的规则排列树中元素,因而可以进行快速的排序和查询的树状数据结构,一般规则是:对于树中任意一个节点,左孩子严格小于根,根严格小于右孩子,有点像大根堆.(只是大根堆中左右孩子关系并不确定,且和根的关系是统一的,而且有上浮和下沉操作使得大根堆总是一棵完全二叉树,其不断弹出堆顶形成有序列的过程叫做堆排序.虽然二叉排序树中也有旋转操作使得树尽量平衡,但是由于数值大小分明的左右孩子,在进行平衡操作时远不如大根堆方便快捷.)对于一棵已经构造完成的排序二叉树,它的中序遍历序列即为升序排列

白话经典算法系列之七 堆与堆排序(转)

堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 由于其它几

利用堆实现堆排序&amp;优先队列

数据结构之(二叉)堆 一文末尾提到"利用堆可以实现:堆排序.优先队列".本文代码实现之. 1.堆排序 假设要将无序数组按非递减(递增)排序,则应使用大(小)顶堆.这里涉及到大堆排序涉及到三种操作:(1).MaxHeapify操作(自顶向下即SiftDown操作):(2).BuildMaxHeap操作(线性时间内将无序数组构造成一个最大堆):(3)将堆顶元素和堆的最后一个元素交换,并将堆元素大小减去1,对堆顶元素调用MaxHeapify操作重新调整为大顶堆,重复直到数组有序.下面是详细的

堆、二叉堆、堆排序

堆.二叉堆.堆排序 堆的概念: n个元素序列 { k1, k2, k3, k4, k5, k6 -. kn } 当且仅当满足以下关系时才会被称为堆: ki <= k2i,ki <= k2i+1 或者 ki >= k2i,ki >= k2i+1 (i = 1,2,3,4 .. n/2) 如果数组的下表是从0开始,那么需要满足 ki <= k2i+1,ki <= k2i+2 或者 ki >= k2i+1,ki >= k2i+2 (i = 0,1,2,3 .. n

数据结构之堆(Heap)的实现

堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构,所以堆也叫做二叉堆. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于   任何一个子节点的键值时为最小堆. 最大堆和最小堆是堆数据结构的重点.堆排序中使用特别的多. 堆的存储一般是用一个数组实现的,当然也可以用链式存储,但是特别麻烦. 如下我