左傾堆以及Java實現

_Git發表於2017-12-19

左傾堆的定義

左傾堆是一棵二叉樹,它的節點除了和二叉樹的節點一樣具有左右子樹指標外,還有兩個屬性:鍵值和零距離。

左傾堆以及Java實現

  1. 鍵值的作用是來比較節點的大小,從而對節點進行排序。
  2. 零距離(英文名NPL,即Null Path Length)則是從一個節點到一個"最近的不滿節點"的路徑長度。不滿節點是指該該節點的左右孩子至少有有一個為NULL。葉節點的NPL為0,NULL節點的NPL為-1。

基本性質

  1. 節點的鍵值小於或等於它的左右子節點的鍵值。
  2. 節點的左孩子的NPL >= 右孩子的NPL。
  3. 節點的NPL = 它的右孩子的NPL + 1。
  4. 節點的NPL值等於其右子節點的NPL值 + 1
  5. 左傾堆的左右子節點及其下方節點構成的堆也分別都是左傾堆

合併兩個左傾堆

  1. 如果一個空左傾堆與一個非空左傾堆合併,返回非空左傾堆。
  2. 如果兩個左傾堆都非空,那麼比較兩個根節點,取較小堆的根節點為新的根節點。將"較小堆的根節點的右孩子"和"較大堆"進行合併。
  3. 如果新堆的右孩子的NPL > 左孩子的NPL,則交換左右孩子。
  4. 設定新堆的根節點的NPL = 右子堆NPL + 1
 /**
     * 合併
     *
     * @param x
     * @param y
     * @return
     */
    private LeftistNode<T> merge(LeftistNode<T> x, LeftistNode<T> y) {
        if (x == null)
            return y;
        if (y == null)
            return x;
        //x結點比y結點大
        if (x.key.compareTo(y.key) > 0) {
            LeftistNode<T> temp = y;
            y = x;
            x = temp;
        }
        x.right = merge(x.right, y);
        if (x.left == null || x.left.npl < x.right.npl) {
            LeftistNode<T> tmp = x.right;
            x.right = x.left;
            x.left = tmp;
        }

        if (x.right == null || x.left == null)
            x.npl = 0;
        else
            x.npl = (x.left.npl < x.right.npl) ? x.left.npl + 1 : x.right.npl + 1;
        return x;
    }


    public void merge(LeftistHeap<T> other) {
        merge(mRoot, other.mRoot);
    }
複製程式碼

原始碼

相關文章