算法导论之 堆排序研究

参考文献1:算法导论第六章讲解 堆排序
参考文献2:<a target=_blank href="http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621">http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621</a>

/****************************************************************************/
/*time:2014.11.15  author:chen stallman             */
/*1.如何建立最大堆                                      */
/*2.把数组转换成最大堆                              */
/*3.把建好的堆中数据与原数组进行数据交换             */
/******************************************************************************/

#include<iostream>
#include<algorithm>

using namespace std;

void swap(int *x, int *y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

//建立以root为i(即根节点为i)的最大堆,利用了递归的思想防止调整之后以largest为父节点的子树不是最大堆
void max_heapify(int a[], int i, int heapsize)
{
	int l = 2 * i;//取其左孩子的坐标
	int r = 2 * i + 1;//取其右孩子的坐标
	int largest;//临时变量,用来保存r、l、r三个节点中最大的值

	if (l<=heapsize&&a[l]>a[i])
		largest = l;
	else
		largest = i;

	if (r<=heapsize&&a[r]>a[largest])
		largest = r;

	if (largest != i)
	{
		swap(&a[i], &a[largest]);
		max_heapify(a, largest, heapsize);
	}
}

//***********************************************
//用自底向上的方法把数组转换成最大堆
void buil_max_heap(int a[], int heapsize)
{
	int i;
	for (i = heapsize / 2; i >= 1; i--)
	{
		max_heapify(a, i, heapsize);
	}
}

//有了上面这个两个辅助功能函数就可以对数组进行堆排序了
void heap_sort(int a[], int len)
{
	int i;
	buil_max_heap(a, len);
	for (i = len; i >= 2; i--)
	{
		swap(&a[1], &a[len]);
		len--;
		max_heapify(a, 1, len);
	}
}

int main()
{
	//这里数组下标从1开始,数组第一个元素没有使用
	int a[] = { 0,12,-3,88,52,6,4,33,2,100,5,20};

	heap_sort(a, 11);

	for (auto i : a)
		cout << i << " ";

	cout << endl;

	return 0;
}

时间: 2024-10-16 08:34:43

算法导论之 堆排序研究的相关文章

【算法导论】堆排序

(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树.二叉堆可以分为两种形式:最大堆和最小堆.若将记录按从大到小排列,建“小”顶堆.若将记录按从小到大排,建“大”顶堆. 说明:在堆排序算法中,我们使用的是最大堆,最小堆通常用于构造优先队列. 算法分析:时间复杂度是O(nlogn).堆排序属于原址排序:任何时候都只需要常数个额外的元素空间存储临时数据.堆排序是不稳定的排序算法. 1 #include <stdio.h> 2 #define LEFT(i) 2 * i 3 #define RIG

算法导论:堆排序

1 //goal: heap sort 2 //time: 9/7/2014 3 //author: zrss 4 //reference: introduction to algorithms 5 6 #include <cstdio> 7 #include <cstring> 8 9 #define MAX_DATA 10 10 11 class MaxHeap { 12 public: 13 MaxHeap(int *data, int size); 14 15 void h

[算法导论]#6 堆排序

草草整理一下,以后再完善一点 堆排序的复杂度是比较稳定的\(O(nlgn)\),并且具有空间原址性. 二叉堆是一个是一个数组,通过类似线段树的方式来表示父结点和子结点 其中1结点代表根,在大根堆中代表最大的数 任何子结点在循环前都可以看作一个平凡堆 大根堆中,每个结点都要比它的子结点大,维护这个性质,只需要将该结点与子结点取一个最大的交换到根,然后将可能违背性质的点递归 #include<bits/stdc++.h> using namespace std; struct heap{ int

【算法导论】学习笔记——第6章 堆排序

堆这个数据结构应用非常广泛,数字图像处理的算法里也见过.似乎记得以前老师上课说需要用树结构实现堆排序,看了一下算法导论才明白其精髓.堆虽然是一棵树,但显然没必要非得用树结构实现堆排序.堆排序的性质很好,算法时间复杂度为O(nlgn). 1. 堆排序的简要说明.二叉堆可以分为两种形式:最大堆和最小堆.在最大堆中,最大堆性质是指除了根以外的所有结点i都要满足: A[PARENT(i)] >= A[i]:在最小堆中,最小堆性质是指除了根以外的所有结点i都要满足: A[PARENT(i)] <= A[

算法导论 第6章 堆排序

堆数据结构实际上是一种数组对象,是以数组的形式存储的,但是它可以被视为一颗完全二叉树,因此又叫二叉堆.堆分为以下两种类型: 大顶堆:父结点的值不小于其子结点的值,堆顶元素最大 小顶堆:父结点的值不大于其子结点的值,堆顶元素最小 堆排序的时间复杂度跟合并排序一样,都是O(nlgn),但是合并排序不是原地排序(原地排序:在排序过程中,只有常数个元素是保存在数组以外的空间),合并排序的所有元素都被拷贝到另外的数组空间中去,而堆排序是一个原地排序算法. 1.在堆排序中,我们通常使用大顶堆来实现,由于堆在

堆排序与优先队列&mdash;&mdash;算法导论(7)

1. 预备知识 (1) 基本概念     如图,(二叉)堆一个数组,它可以被看成一个近似的完全二叉树.树中的每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且从左向右填充.堆的数组A包括两个属性:A.length给出了数组的长度:A.heap-size表示有多少个堆元素保存在该数组中(因为A中可能只有部分位置存放的是堆的有效元素).     由于堆的这种特殊的结构,我们可以很容易根据一个结点的下标i计算出它的父节点.左孩子.右孩子的下标.计算公式如下: parent(i) =

算法导论 第6章 堆排序(简单选择排序、堆排序)

堆数据结构实际上是一种数组对象,是以数组的形式存储的,可是它能够被视为一颗全然二叉树,因此又叫二叉堆.堆分为下面两种类型: 大顶堆:父结点的值不小于其子结点的值,堆顶元素最大 小顶堆:父结点的值不大于其子结点的值,堆顶元素最小 堆排序的时间复杂度跟合并排序一样,都是O(nlgn),可是合并排序不是原地排序(原地排序:在排序过程中,仅仅有常数个元素是保存在数组以外的空间),合并排序的全部元素都被复制到另外的数组空间中去,而堆排序是一个原地排序算法. 1.在堆排序中,我们通常使用大顶堆来实现,因为堆

《算法导论》学习摘要chapter-6——堆排序

本章堆排序内容是<算法导论>教材第二部分<排序与顺序统计量>的第一讲. 堆排序,这是一种O(nlgn)时间的原址排序算法.它使用了一种被称为堆的数据结构,堆还可以用来实现优先级队列. 1.堆的概念 数组R[1...n]中,n个关键字序列k1,k2,-,kn,当且仅当该序列满足如下性质(简称为堆性质,以大根堆为例): ki >= k(2i)且ki >= k(2i+1)(1≤i≤ n/2)大根堆则换成>=号.相当于完全二叉树的非叶子结点,K(2i)则是左子节点,k(2

算法导论——lec 06 堆排序

堆数据结构是一种数组对象,它可以被视为一颗完全二叉树,树中每个节点和数组中存放该节点值的那个元 素对应.如果表示堆的数组为A,那么树的根为A[1]. 一. 堆 1. 表示堆的数组A是一个具有两个属性的对象:length(A)是数组中的元素个数,heap-size(A)是存放在A中的堆的 元素个数:A[heap-size(A)]之后的元素都不属于相应的堆.也就是:Heap-size(A)<=length(A). 2. 给定某个节点的下标i,其父节点PARENT(i),左儿子LEFT(i)和右儿子R