資料結構之樹之不同種類篇

2021-07-10 13:07:24 字數 4145 閱讀 7179

typedef

struct treenode

;

將關鍵字k插入到二叉搜尋樹

若是已經存在,就不再插入

所以插入都是插入在葉子節點

比如已經有了5->6->9,

當插入7的時候,7並不會插入在6和9之間,而是插入在9的左邊

找到要插入的位置節點,當前位置為空時

新建乙個節點,給其賦當前值,再使其指向當前的父節點

int bst_insert(treenode *root, int k, treenode*

parent

=null)

else

if(k==root->val)

return

0;//樹中存在相同的關鍵字

else

if(kval)

return bst_insert(root->left,k,root);

else

return bst_insert(root->right,k,root);

}

用陣列arry建立二叉查詢樹

void create_bst(treenode* root,int arr,int n)
非遞迴:

treenode* bst_search_nonrecur(treenode* root, int key)

return t;

}

treenode* bst_minnum(treenode* root)

treenode* bst_maxnum(treenode* root)

二叉搜尋樹的最近共同祖先(lowestcommonancestor)

假定樹中存在這兩個點的值

檢查當前節點

if value1和value2都小於當前節點的值

檢查左子節點

if value1 和value2 都大於當前節點的值

檢查右子節點

否則當前節點就是最近共同祖先

非遞迴:

treenode* find_lca(treenode* root,int value1,int value2)

return null;//only if empty tree;

}

問題:給定乙個二叉查詢樹的節點,求出它在中序遍歷中的前驅和後繼。

後繼:

兩種情況

若結點 x 的右子樹不為空,則 x 的後繼就是它的右子樹中關鍵字值最小的結點;

若結點 x 的右子樹為空,為了找到其後繼,從結點 x 開始向上查詢,直到遇到乙個祖先結點 y,它的左兒子也是結點 x 的祖先,則結點 y 就是結點 x 的後繼。如下圖

}兩種情況

若結點 x 的左子樹不為空,則 x 的前驅是它的左子樹中關鍵字值最大的結點;

若結點 x 的左子樹為空,為了找到其前驅,從結點 x 開始向上查詢,直到遇到乙個祖先結點 y,它的右兒子也是結點 x 的祖先,則結點 y 就是結點 x 的前驅。

treenode* bst_predecessor(treenode* node)

return p;

}

二叉查詢樹的刪除操作相對複雜一點,它要按3種情況來處理:

1.若被刪除結點z是葉子結點,則直接刪除,不會破壞二叉排序樹的性質;

2. 若結點z只有左子樹或只有右子樹,則讓z的子樹成為z父結點的子樹,代替z的位置;

3. 若結點z既有左子樹,又有右子樹,則用z的後繼(沒有左孩子)代替z(先刪除後繼結點,再將後繼的內容去替換z),而刪除後繼結點的過程就是第一種或第二種情況。

說明:第三種情況,因為z有兩個子女,所以它的後繼肯定是它右子樹中的最左邊(最小值),也就是說它的後繼要麼是葉子,要麼只有乙個右孩子

void bst_delete(treenode* root,treenode* z)

else

root->

null;

free(z);

}else

if(z->left!=

null

&&z->right==

null)

else

root=z->left; //刪除左斜單支樹的根結點

free(z);

}else

if(z->right!=

null

&&z->left==

null)

else

z->

parent

->right=z->right;

}else

root=z->right; //刪除右斜單支樹的根結點

free(z);

}else

}

對於乙個高度為h的二叉查詢樹來說,刪除操作和插入操作一樣,都是o(h)

參考1

參考2由於紅黑樹本質上就是一棵二叉查詢樹,所以在了解紅黑樹之前,咱們先來看下二叉查詢樹。

二叉查詢樹(binary search tree),也稱有序二叉樹(ordered binary tree),排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:

因為,一棵由n個結點,隨機構造的二叉查詢樹的高度為lgn,所以順理成章,一般操作的執行時間為o(lgn).(至於n個結點的二叉樹高度為lgn的證明,可參考演算法導論 第12章 二叉查詢樹 第12.4節)。

前面我們已經說過,紅黑樹,本質上來說就是一棵二叉查詢樹,但它在二叉查詢樹的基礎上增加了著色和相關的性質使得紅黑樹相對平衡,從而保證了紅黑樹的查詢、插入、刪除的時間複雜度最壞為o(log n)。

但它是如何保證一棵n個結點的紅黑樹的高度始終保持在h = logn的呢?這就引出了紅黑樹的5條性質:

每個結點要麼是紅的,要麼是黑的。

根結點是黑的。

每個葉結點(葉結點即指樹尾端nil指標或null結點)是黑的。

如果乙個結點是紅的,那麼它的倆個兒子都是黑的。

對於任一結點而言,其到葉結點樹尾端nil指標的每一條路徑都包含相同數目的黑結點。

正是紅黑樹的這5條性質,使得一棵n個結點是紅黑樹始終保持了logn的高度,從而也就解釋了上面我們所說的「紅黑樹的查詢、插入、刪除的時間複雜度最壞為o(log n)」這一結論的原因。

如下圖所示,即是一顆紅黑樹(下圖引自wikipedia: ):

上文中我們所說的 「葉結點」 或」null結點」,它不包含資料而只充當樹在此結束的指示,這些結點以及它們的父結點,在繪圖中都會經常被省略。

當我們在對紅黑樹進行插入和刪除等操作時,對樹做了修改,那麼可能會違背紅黑樹的性質。

為了繼續保持紅黑樹的性質,我們可以通過對結點進行重新著色,以及對樹進行相關的旋轉操作,即修改樹中某些結點的顏色及指標結構,來達到對紅黑樹進行插入或刪除結點等操作後,繼續保持它的性質或平衡。

樹的旋轉,分為左旋和右旋,以下借助圖來做形象的解釋和介紹:

1.左旋

如上圖所示:

當在某個結點pivot上,做左旋操作時,我們假設它的右孩子y不是nil[t],pivot可以為任何不是nil[t]的左孩子結點。

左旋以pivot到y之間的鏈為「支軸」進行,它使y成為該孩子樹新的根,而y的左孩子b則成為pivot的右孩子。

資料結構之 樹

1.雙親表示法 下標 資料 parentid 2.孩子表示法 data child1 child2 child3 3.雙親孩子表示法 下標 parentid firstchildid secondchildid 節點 下標 next 頁的話next應該是null 4.孩子兄弟表示法 data 第一次...

資料結構之樹

一 樹的基本概念 樹 tree 是元素的集合,樹有多個節點可以儲存元素 二 二叉樹 每個節點最多有兩個子節點的樹稱為二叉樹 常用來做二分查詢 binary search 等 三 b樹 即二叉搜尋樹 binary search tree 是一種特殊形態的二叉樹 1 所有節點最多擁有2個子節點 2 所有...

資料結構之樹

樹是節點的有限集合.度 a的度是3 b的度是2 d的度是2 c的度為0 當前節點的直接分支 葉子 終端節點就是葉子 e f g h c 根 非終端節點就是根 a b d 有序樹 如果e f不可以隨意換順序 就是有序樹 無序樹 如果 e f可以隨意換順序而且不影響邏輯 祖先 對e來說 b,a都是祖先 ...