python排序--堆排序

樹的概念

樹是一種數據結構 比如:目錄結構
樹是一種可以遞歸定義的數據結構
樹是由n個節點組成的集合:

  • 如果n=0,那這是一棵空樹
  • 如果n>0,那存在1個節點作爲樹的根節點,其他節點可以分爲m個集合,每個集合本身又是一顆樹
  • 一些概念
  • 根節點
  • 樹的深度(高度)
  • 樹的度
  • 孩子節點/父節點
  • 子樹
    在這裏插入圖片描述

二叉樹–度不超過2的樹

二叉樹 度不超過2的樹

每個節點最多有兩個孩子節點

兩個孩子節點被區分爲左孩子節點和右孩子節點
在這裏插入圖片描述滿二叉樹

  • 一個二叉樹,如果每一層的結點數都達到最大值,則這個二叉樹就是滿二叉樹

完全二叉樹

  • 葉節點只能出現在最下層和次下層,並且最下面一層的結點都集中在該層最左邊的若干位置的二叉樹
    在這裏插入圖片描述二叉樹的存儲方式(表示方式)
    鏈式存儲方式
    順序存儲方式(用列表存取)
    堆是一個特殊的完全二叉樹
    因爲是堆排序,所以先了解一下順序存儲方式
    在這裏插入圖片描述### 堆排序–什麼是堆
    堆:一種特殊的完全二叉樹
  • 大根堆:一棵完全二叉樹,滿足任一節點都比其他孩子節點大
  • 小根堆:一棵完全二叉樹,滿足任一節點都比其他孩子節點小
    在這裏插入圖片描述

堆的向下調整

假設:節點的左右子樹都是堆,但自身不是堆
當根節點的左右子樹都是堆時,可以通過一次向下的調整來將其變換成一個堆
在這裏插入圖片描述
在這裏插入圖片描述

堆排序過程

  1. 建立堆
  2. 得到堆頂元素,爲最大元素
  3. 去掉堆頂,將堆最後一個元素放到堆頂,此時可通過一次調整重新使堆有序
  4. 堆頂元素爲第二大元素
  5. 重複步驟3,直到堆變空

構造堆

從最後面的小節點調整,慢慢構造成整個堆

堆實現代碼

def sift(li, low, high):
    """
    
    :param li: 列表
    :param low: 堆的根節點位置
    :param high: 堆的最後一個元素的位置
    :return: 
    """
    i = low # i最開始指向根節點
    j = 2 * i + 1 # j開始是左孩子
    tmp = li[low] # 把堆頂存起來
    while j <= high: # 只要j位置有數
        if j+1<= high and li[j+1] > li[j]: # 如果右孩子有並且比較大
            j = j + 1 # j指向右孩子節點,不能互換
        if li[j] > tmp:
            li[i] = li[j]
            i = j  # 往下看一層
            j = 2 * i + 1
        else:  #tmp更大,把tmp放到i的位置上
            # li[i] = tmp  # 把tmp放到某一級領導那兒
            break
    li[i] = tmp # 把tmp放到葉子節點上
def head_sort(li):
    n = len(li)
    for i in range((n-2)//2, -1, -1):
        # i 表示建堆的時候調整的部分的根的下標
        sift(li, i, n-1)
    # 建堆完成了
    for i in range(n-1, -1, -1):
        # i 指向當前堆的最後一個元素
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i-1) # i-1是新的high

li = [i for i in range(100)]
import random
random.shuffle(li)
print(li)
head_sort(li)
print(li)

堆排序時間複雜度

sift函數–>logn,走樹的高度(深度)
head_sort函數–>nlogn
堆排序的時間複雜度:nlogn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章