Heap堆的概念,排序,删除和插入

http://fangjian0423.github.io/2016/04/09/heap-heapsort/

堆的概念:

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/2)

比如 { 1,3,5,10,15,9 } 这个序列就满足 [1 <= 3; 1 <= 5], [3 <= 10; 3 <= 15], [5 <= 9] 这3个条件,这个序列就是一个堆。

所以堆其实是一个序列(数组),如果这个序列满足上述条件,那么就把这个序列看成堆。

堆的实现通常是通过构造二叉堆,因为二叉堆应用很普遍,当不加限定时,堆通常指的就是二叉堆。

二叉堆的概念:

二叉堆是一种特殊的堆,是一棵完全二叉树或者是近似完全二叉树,同时二叉堆还满足堆的特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆。

当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆。 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。


上图中的最小堆对应的序列是: [1,3,5,9,10,15] 满足最小堆的特性(父节点的键值小于或等于任何一个子节点的键值,并且也满足堆的性质 [1 <= 3; 1 <= 5], [3 <= 9; 3 <= 10], [5 <= 15])

上图中的最大堆对应的序列是: [15,10,9,7,5,3] 满足最大堆的特性(父节点的键值大于或等于任何一个子节点的键值,并且也满足堆的性质 [15 >= 10; 15 >= 9], [10 >= 7; 10 >= 5], [9 >= 3])

堆的操作

堆排序

堆排序指的是对堆这种数据结构进行排序的一种算法。其基本思想如下,以最大堆为例:

将数组序列构建成最大堆[ A1, A2, A3 .. An],这个堆是一个刚初始化无序区,同时有序区为空

堆顶元素A1与最后一个元素An进行交换,得到新的有序区[An],无序区变成[A1 … An-1]

交换之后可能导致[A1 … An-1]这个无序区不是一个最大堆,[A1 … An-1]无序区重新调整成最大堆。重复步骤2,A1与An-1进行交换,得到新的有序区[An,An-1],无序区变成[A1 … An-2].. 不断重复,直到有序区的个数为n-1才结束排序过程

构造堆的过程如下(以最大堆为例):

从最后一个非叶子节点开始调整,遍历节点和2个子节点,选择键值最大的节点的键值代替父节点的键值,如果进行了调整,调整之后的两个子节点可能不符合堆特性,递归调整。一直直到调整完根节点。

以序列[3,5,15,9,10,1]为例进行的堆排序:

首先第1步先把数组转换成完全二叉树:

最大堆构成

接下来是第2、3步构造有序区和无序区:

最大堆得顺序

构造完之后有序区的元素依次是:1,3,5,9,10,15

简单地使用java写一下堆排序:

public class HeapSort {

public static void maxHeapify(int[] arr, int size, int index) {

int leftSonIndex = 2 * index + 1;

int rightSonIndex = 2 * index + 2;

int temp = index;

if(index <= size / 2) {

if(leftSonIndex < size && arr[temp] < arr[leftSonIndex]) {

temp = leftSonIndex;

}

if(rightSonIndex < size && arr[temp] < arr[rightSonIndex]) {

temp = rightSonIndex;

}

// 左右子节点的值存在比父节点的值更大

if(temp != index) {

swap(arr, index, temp); // 交换值

maxHeapify(arr, size, temp); // 递归调整

}

}

}

public static void heapSort(int[] arr, int size) {

// 构造成最大堆

buildMaxHeap(arr, arr.length);

for(int i = size - 1; i > 0; i --) {

// 先交换堆顶元素和无序区最后一个元素

swap(arr, 0, i);

// 重新调整无序区

buildMaxHeap(arr, i - 1);

}

}

public static void buildMaxHeap(int[] arr, int size) {

for(int i = size / 2; i >= 0; i --) { // 最后一个非叶子节点开始调整

maxHeapify(arr, size, i);

}

}

public static void swap(int[] arr, int i, int j) {

int temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

public static void main(String[] args) {

int[] arr = { 3, 5, 15, 9, 10, 1};

System.out.println("before build: " + Arrays.toString(arr)); // before build: [3, 5, 15, 9, 10, 1]

buildMaxHeap(arr, arr.length);

System.out.println("after build: " + Arrays.toString(arr)); // after build: [15, 10, 3, 9, 5, 1]

heapSort(arr, arr.length);

System.out.println("after sort: " + Arrays.toString(arr)); // after sort: [1, 3, 5, 9, 10, 15]

}

}

添加

在最大堆[ 15,10,9,7,5,3 ]上添加一个新的元素 11 ,执行的步骤如下:

insert new node

删除

在最大堆[ 15,10,9,7,5,3 ]上删除元素 10 ,执行的步骤如下:

delete one node
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 排序算法是最基本最常用的算法,不同的排序算法在不同的场景或应用中会有不同的表现,我们需要对各种排序算法熟练才能将它...
    若丶天下阅读 439评论 0 1
  • 排序算法是最基本最常用的算法,不同的排序算法在不同的场景或应用中会有不同的表现,我们需要对各种排序算法熟练才能将它...
    AlvinL阅读 71,441评论 64 1,739
  • 简单 文/初阳 我打算好了, 这一世来的不是太容易, 因此我选择三处景: 一处走过桥后的回头; 一处奋力...
    水中卍初阳阅读 185评论 1 1
  • 天气 晴 体重 不知道 早 没吃 午 食堂 米线5元+饼2.5元+果粒橙三块五 晚 饭馆聚餐27元 穿 雪地靴+加...
    Mikako阅读 157评论 0 0
  • 《红楼梦》是一部具有世界影响力的小说作品。曹雪芹用超现实手法写下了一本没有写完的书,让一批又一批的红学研究者...
    舍得LL阅读 282评论 0 0