一棵二叉樹 可以為空白 如果不為空白 則滿足以下性質
(1)非空左子樹的所有索引值小於其根節點索引值
(2)非空右子樹的所有索引值大於其根節點索引值
(3)左右子樹都是二叉搜尋樹
最大和最小元素
最大元素一定在最右端分支的端節點上
最小元素一定在最左端分支的端節點上
二叉樹的構建:
首先定義節點,節點結構如下
class BstNode {friend class Bst; //設定為友元類private:Elementtype data; //用來儲存資料BstNode* leftChild; //左子BstNode* rightChild; //右子void show(int i); //顯示當前結點情況};show函數用來顯示當前節點的節點號以及資料內容
根據數學上的定理: 一個節點編號若為i 則其左子編號為2*i 右子編號為2*i+1
void BstNode::show(int i) {cout << "the node num" << i << " data:" << data << endl;if (leftChild) leftChild->show(2 * i); //顯示左節點if (rightChild) rightChild->show(2 * i + 1); //顯示右節點}
二叉樹的插入:
(1)首先判斷根節點是否為空白 如果為空白 則根節點為作為插入點
(2)如果要插入的節點數值比當前節點大 則遍曆右節點
如果要插入的節點數值比當前節點小 則遍曆左節點 知道遇到null 指標 則該位置為插入點
插入代碼如下
bool Bst::BinaryInsert(Elementtype data) {BstNode *p; //遍曆指標BstNode *q; //遍曆指標的上一個指標p = root;q = NULL;//尋找合適的位置while (p) {q = p; //在遍曆前 先保留該節點if (data == p->data)return false; //發生重複的情況else if (data < p->data) {p = p->leftChild; //向左邊遍曆}else if (data > p->data) {p = p->rightChild; //向右邊遍曆}}//構建新的指標p = new BstNode();p->data = data;p->leftChild = NULL;p->rightChild = NULL; if (!root) { //如果是空節點 則將root設定為proot = p;return true;}if (p->data < q->data)q->leftChild = p;elseq->rightChild = p;return true;}
二叉樹的尋找:
尋找的原理和插入相同 都是通過一個元素去進行遍曆 找到合適的位置進行插入
void Bst::BinarySearch(Elementtype data) { BstNode *p; //遍曆指標p = root; //從根節點開始遍曆while (p) {if (p->data == data) {cout << "find element data!" << endl;return;}else if (data < p->data) {p = p->leftChild; //尋找左邊元素}else {p = p->rightChild; //尋找右邊元素}}cout << "can not find the element" << endl;return;}
二叉樹的刪除:
要刪除的是分葉節點:直接刪除 並再次修改父節點指標為NULL
要刪除的節點只有一個左子或只有一個右子:刪掉節點後把左子或右子掛在其父節點上
更加複雜的情況:都有左右子樹或者層數很深
在二叉樹左子樹中找一個最大值 進行替換後刪除
或者在二叉樹右子樹中找一個最小值 進行替換後刪除
代碼如下:
BstNode* Bst::BinaryDelete(BstNode* targetNode, Elementtype data) {if (!targetNode) { /*如果遞迴後依然得到空節點 則返回*/cout << "can not find the element!" << endl;}else if (data < targetNode->data) { //沒有找到節點的話 遞迴繼續尋找節點targetNode->leftChild = BinaryDelete(targetNode->leftChild, data); //去左子樹尋找節點}else if (data > targetNode->data) { //沒有找到節點的話 遞迴繼續尋找節點targetNode->rightChild = BinaryDelete(targetNode->rightChild, data); //去右子樹尋找節點}else {BstNode* Tmp = NULL;if (targetNode->leftChild && targetNode->rightChild) { //左右節點都存在的情況Tmp = BinaryFindMin(targetNode->rightChild); targetNode->data = Tmp->data;targetNode->rightChild = BinaryDelete(targetNode->rightChild, targetNode->data); }else { //只存在左節點或只存在右節點Tmp = targetNode; //先暫存元素if (targetNode->leftChild)targetNode = targetNode->leftChild; //被刪元素用其左子節點代替 if (targetNode->rightChild)targetNode = targetNode->rightChild; //被刪元素用其右子節點代替delete Tmp; //刪除節點}}return targetNode; }
注:被刪除的節點是子樹的最小節點 所以肯定只有右子節點或沒有子節點