算法之堆排序

基本认识

  1. 定义:堆可以定义为一颗二叉树,树的每一个节点包含一个键,且这棵二叉树是完全二叉树,即除了最后一层,树的每一层都是满的,最后一层右边可能有缺位。



    由于结点左侧缺位,非堆
  2. 大顶堆:父节点的键值要大于或者等于子女结点的键值。
  3. 小顶堆:父节点的键值要小于或者等于子女结点的键值。
  4. 补充:用数组实现堆,堆并不是实际存在,认为定义的一个逻辑 ;结点n的左孩子为2n + 1,右孩子为2n + 2,结点m的父节点为(m - 1)/2


大顶堆的实现堆排序

  1. 构建大顶堆:遍历待排数组,判断每个元素与父节点元素的大小,如果孩子结点元素比父结点元素大,交换两个元素的位置,直到孩子结点元素小于等于父结点元素大小。
    步骤一:结点元素位置为 i,所以元素开始比较位置index = i
    步骤二:判断 index 位置(孩子元素)与 (index - 1)/2 位置(父元素)大小
    a. 如果arr[index] > arr[(index-1)/2],交换index位置与(index-1)/2位置元素, index = (index-1)/2,执行步骤二
    b. 如果arr[index] <= arr[(index-1)/2],执行步骤三
    步骤三:i += 1,如果 i <= len(arr),执行步骤二,否则,结束算法

  2. 获取有序数组
    步骤一:堆顶位置为 l,堆最后一个元素位置 r
    步骤二:将 r 位置与 l 位置元素(堆顶位置元素,也即是最大元素)交换, r -= 1(解析:将r位置与对顶位置元素交换,那么对顶位置就会在待排数组最后位置上,即待排数组中最大元素将会被换到待排元素最后位置上,所以大于等于r位置上的元素都有序),此时,大顶堆结构被破坏(因为堆顶位置非最大元素),待调整结点位置为 index = l
    步骤三:对index结点进行调整
    a. 左孩子结点位置为 left = index *2 + 1,右孩子结点位置为 left + 1
    b. left <= r:如果右孩子不存在(left +1 > size)或者左孩子元素比有孩子元素大,maxIndex = left,否则maxIndex = left + 1
    c. 如果arr[index] >= arr[maxIndex],交换两个位置元素,index = maxIndex,执行步骤三,否则结束调整
    d. left > r,待调整结点无孩子结点,结束调整
    步骤四:如果 r >= l,执行步骤二, 否则结束算法

图解过程

  1. 待排数组

2.构建大顶堆
  1. 获取有序数组

代码实现

def headSort(arr):
    if(len(arr) <= 1):
        return
    for i in range(len(arr)):
        headInsert(arr, i)
    r = len(arr) - 1
    while(r >= 1):
        arr[0], arr[r] = arr[r], arr[0]
        r -= 1
        heapify(arr, 0, r)

def headInsert(arr, index):
    index_half = int((index - 1)/2)
    while(arr[index] > arr[index_half]):
        arr[index], arr[index_half] = arr[index_half], arr[index]
        index = index_half
        index_half = int((index - 1)/2)

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

推荐阅读更多精彩内容

  • 详细代码请参考Algorithm。参考代码比文字好理解。 堆排序是时间复杂度为O(N*lgN)的排序方法。是指利用...
    一个人在路上走下去阅读 1,503评论 1 2
  • 时间复杂度:O(Nlog(N))额外空间复杂度:O(1)是否可实现稳定性:否 思路: 把数组逻辑上看成一个二叉树,...
    一凡呀阅读 647评论 0 0
  • 堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O...
    4e70992f13e7阅读 1,128评论 0 0
  • 堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构(通常堆是通过一维数组来实现的),并...
    BEYOND黄阅读 191评论 0 2
  • 完全二叉树的基本概念 可能你会疑问,为什么我们明明讲的是堆排序,怎么又扯上了二叉树的概念了,答案就是,我们这里的堆...
    再见远洋阅读 1,069评论 0 7