二叉查詢樹(binary search tree),也稱有序二叉樹(ordered binary tree),排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
1. 若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
2. 若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
3. 任意節點的左、右子樹也分別為二叉查詢樹。
4. 沒有鍵值相等的節點(no duplicate nodes)。
而我們可以利用二叉搜尋樹的特點,來進行轉換,如下圖
根據二叉搜尋樹的特點,如果中序遍歷這棵樹,那麼我們可以拿到乙個有序的遍歷序列,如果能在遍歷期間,將這些被遍歷的結點的指標進行重置,使其變成右前後指向關係,那剛好可以滿足題目的要求。可是,具體如何做呢,接下來就進一步分析。
中序遍歷時,將整棵樹分為三部分,先訪問左子樹,在訪問根結點,最後訪問右子樹,遞迴訪問子樹。同樣的,我們可以將搜尋樹分為三部分,把左子樹和右子樹都轉換成排序的雙向鍊錶之後,將左子樹的最右結點(最大值)和根結點鏈結起來,將右子樹的最左結點(最小值)和根結點鏈結起來,那麼整棵樹可以說基本已經調整好了。
具體實現:定義乙個尾指標tail,用來標識當前鍊錶的尾結點。將結點的_left看作是prev,_right看作是next,最後對頭節點和尾結點進行處理。
最開始先找到鍊錶的頭節點,也就是樹的最左結點,對頭節點的指標指向進行修改,讓tail指向當前結點,遞迴實現即可。
#pragma once
templatestruct binarytreenode
};templateclass binarysearchtree
bool insert(const k& key, const v& value)
node* parent = null;
node* cur = _root;
while (cur)
else if (cur->_key > key)
else
}//判斷插入點為父親的左孩子還是右孩子
if (parent->_key > key)
else
return true; }
void convert()
_root = head;
} void convertnode(node* _root, node** tail)
protected:
node* _root;
};void testbinareysearchtree()
將二叉搜尋樹轉換成乙個排序雙向鍊錶
將二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。定義 二叉搜尋樹也叫二叉查詢樹或二叉排序樹,它可以是一顆空樹,或者是滿足如下性質的二叉樹 若該樹的左子樹不為空,則左子樹上所有節點的值均小於根節點的值,若該樹的右子樹不為空,則右子樹上所有節點的值均大於根節點...
將二叉搜尋樹轉換成乙個排序的雙向鍊錶
題目具體 將二叉搜尋樹轉換成乙個排序的雙向鍊錶,要求不能建立任何新的結點,只能調整樹中結點指標的指向,也就是left當prev,right當next。以如下的二叉樹為例 要將此二叉樹轉化稱為如下的雙向鍊錶 將pleft指標當作指向前乙個結點的指標,將pright指標當作指向後乙個結點的指標。則步驟可...
將二叉搜尋樹轉換成排序的雙向鍊錶
二叉搜尋樹的中序遍歷得到的是乙個已排序的序列。因此可以仿照中序遍歷,依次訪問結點並改變結點的指向,使其構成乙個雙向鍊錶。在訪問當前結點之前,需要先訪問左子樹,並改變左子樹中的結點指向,使其構成雙向鍊錶。同時需要獲取左子樹構成雙向鍊錶的頭和尾結點。頭結點是整棵樹構成的雙向鍊錶的頭結點,而尾結點是左子樹...