樹(樹,二叉樹,二叉查詢樹)

2021-08-04 04:12:58 字數 3607 閱讀 5379

1.定義: n(n≥0)個結點構成的有限集合。當n=0時,稱為空樹

2.對於任一棵非空樹(n> 0),它具備以下性質:

(1)、樹中有乙個稱為「根(root)」的特殊結點,用 r 表示;

(2)、其餘結點可分為m(m>0)個互不相交的有限集t1,t2,… , 其中每個集合本身又是一棵樹,稱為原來樹的子樹。

3.樹的一些性質:

(1)、子樹是不相交的;

(2)、除了根結點外,每個結點有且僅有乙個父結點;

(3)、 一棵n個結點的樹有n-1條邊。

4、樹的一些基本術語

(1). 結點的度(degree):結點的子樹個數

(2).樹的度:樹的所有結點中最大的度數

(3). 葉結點(leaf):度為0的結點

(4). 父結點(parent):有子樹的結點是其子樹

的根結點的父結點

(5). 子結點(child):若a結點是b結點的父結

點,則稱b結點是a結點的子結點;子結點也

稱孩子結點。

(6). 兄弟結點(sibling):具有同一父結點的各

結點彼此是兄弟結點

(7). 路徑和路徑長度:從結點n1到nk的路徑為乙個結點序列

n1 , n2,… , nk, ni是 ni+1的父結點。路徑所包含邊的個數為路徑的長度。

(8). 祖先結點(ancestor):沿樹根到某一結點路徑上的所有結點都是這個結點的祖先結點。

(9). 子孫結點(descendant):某一結點的子樹

中的所有結點是這個結點的子孫。

(10). 結點的層次(level):規定根結點在1層,

其它任一結點的層數是其父結點的層數加1。

(11). 樹的深度(depth):樹中所有結點中的最

大層次是這棵樹的深度。

5.二叉樹:乙個有窮的結點集合。這個集合可以為空,若不為空,則它是由根結點和稱為其左子樹和右子樹的兩個不相交的二叉樹組成。

(1)、斜二叉樹:只有左兒子或者只有右兒子

(2)、完美二叉樹(滿二叉樹):每個結點都有兩個兒子,除了最下面 一層的葉。

(3)、完全二叉樹:有n個結點的二叉樹,對樹中結點按從上至下、從左到右順序進行編號,編號為i(1 ≤ i ≤ n)結點與滿二叉樹中編號為 i 結點在二叉樹中位置相同。

(4)、二叉樹幾個重要性質:

(1. 乙個二叉樹第 i 層的最大結點數為:2^(i-1) (i >= 1)。

(2.深度為k的二叉樹有最大結點總數為: 2k-1,k>=1。

(3. 對任何非空二叉樹 t,若n0表示葉結點的個數、n2是度為2的非葉結點個數,那麼兩者滿足關係n0= n2+1。

(5)、二叉樹的儲存:陣列或者鍊錶

(1.陣列儲存:對於完全二叉樹,陣列儲存可以保證連續,並且能夠找到父子關係,但是對於一般的二叉樹,陣列實現雖然也能夠找到對應的父子關係,但是浪費空間很大。

(2.鍊錶儲存:

鍊錶儲存的結構體構造(elementtype為資料型別):

struct treenode;

typedef

struct treenode node;

(6)、二叉樹的遍歷:

(1.先序遍歷:根結點,左子樹,右子樹。

核心**:

void preorder_tree(node* tree)

}

(2.中序遍歷:左子樹、根、右子樹

核心**:

void midorder_tree(node* tree)

}

(3.後序遍歷:左子樹、右子樹、根。

核心**:

void postorder_tree(node* tree)

}

6、二叉查詢樹:它的左子樹中所有關鍵字的值小於樹中的每個節點,而它的右子樹的所有關鍵字的值大於樹中的每個節點。

1-1.查詢操作的核心**:
node * find(int x,node* tree)

1-2.查詢最大值操作的核心**:
node* findmax(node* tree)//遞迴實現 

1-3.查詢最小值操作的核心**:
node * findmin(node *tree)//非遞迴實現 

return tree;

}

2、插入操作:插入操作的關鍵是找到插入的位置,尋找位置的過程可以根據find函式類推。

核心**:

node* insert(int x,node* tree)

tree->

data

= x;

tree->left = tree->right =

null;

}//開始找插入的位置

else

if(tree->

data

> x)//遞迴插入左子樹

tree->left = insert(x,tree->left);

else

if(tree->

data

< x)//遞迴插入右子樹

tree->right = insert(x,tree->right);

/*else x存在,不做任何操作,返回原樹*/

return tree;

}

注意:遞迴應保留前乙個結點的值,這樣才能是插入連線起來,如果把**「tree->left = insert(x,tree->left);」中的左邊改為return,就跟查詢很像了,就不能實現插入的操作。最後不要忘記返回tree!

3.刪除操作:

!!!

有三種情況:(1)、要刪除的結點沒有子樹,這種情況直接將其刪除再將父結點置為null

(2)、要刪除的結點有乙個孩子,將要刪除的結點的父結點指向刪除結點的孩子節點。

(3)、最複雜的一種情況,刪除的結點有左兒子和右兒子。用另乙個結點代替要刪除的結點:左子樹的最大值,右子樹的最小值

!!!

核心**:

node* delet(int x,node* tree)

else

if(x > tree->

data)

tree->right = delet(x,tree->right);//右子樹遞迴刪除

else

if(x < tree->

data)

tree->left = delet(x,tree->left);//左子樹遞迴刪除

else

//找到x結點

else

//被刪除的有乙個子結點或沒有子結點的

}return tree;

}

以上是關於樹的基本概念;二叉樹的一些概念、二叉樹的實現以及二叉樹的遍歷;二叉查詢樹的一些基本操作(包括查詢元素,查詢最值,插入結點,刪除結點)。

關於樹的完整**將在後面補充。

二叉樹 二叉查詢樹

構建二叉樹,判斷是否為二叉查詢樹,遞迴先序遍歷,非遞迴中序遍歷 include include include include using namespace std 二叉樹結點 struct treenode 鍊錶結點 struct listnode struct tempnodetempnode...

二叉樹 二叉查詢樹

二叉樹 binary tree 一種樹型結構,每個節點最多擁有兩個節點。如下圖 幾種型別的二叉樹 1.full binary tree 每個節點的孩子數 是 0 或者 2.對高度沒有要求。如下圖 2.perfect binary tree 這個就是最完美的樹,顧名思義,所有葉子節點都有相同的深度,並...

樹 二叉樹及二叉查詢樹

n n 0 個結點的有限集。如果 n 0,稱為空樹 如果 n 0,則 1 有且僅有乙個特定的稱為根 root 的結點,根只有直接後繼,沒有直接前驅 2 當n 1,除根外其它結點劃分為 m m 0 個互不相交的有限集t1,t2 tm,其中每個集合本身又是一棵樹,稱為根的子樹 subtree 樹的結點 ...