樹 二叉樹及二叉查詢樹

2021-07-12 05:07:11 字數 3633 閱讀 5660

n (n >= 0) 個結點的有限集。如果 n = 0,稱為空樹;如果 n > 0,則

1)有且僅有乙個特定的稱為根(root)的結點,根只有直接後繼,沒有直接前驅;

2)當n > 1,除根外其它結點劃分為 m (m >0) 個互不相交的有限集t1, t2 ,…, tm,其中每個集合本身又是一棵樹,稱為根的子樹(subtree)。

樹的結點:包含乙個資料元素及若干指向子樹的分支;

孩子結點:結點的子樹的根稱為該結點的孩子;

雙親結點:b 結點是a 結點的孩子,則a結點是b 結點的雙親;

兄弟結點:同一雙親的孩子結點; 堂兄結點:同一層上結點;

祖先結點: 從根到該結點的所經分支上的所有結點子孫結點:以某結點為根的子樹中任一結點都稱為該結點的子孫

結點層:根結點的層定義為1;根的孩子為第二層結點,依此類推;

樹的深度:樹中最大的結點層

結點的度:結點子樹的個數

樹的度: 樹中最大的結點度。

葉子結點:也叫終端結點,是度為 0 的結點;

分枝結點:度不為0的結點;

有序樹:子樹有序的樹,如:家族樹;

無序樹:不考慮子樹的順序;

定義:一棵二叉樹是結點的乙個有限集合,該集合或者為空,或者是由乙個根結點加上兩棵分別稱為左子樹和右子樹的、互不相交的二叉樹組成。

特點:每個結點至多只有兩棵子樹(二叉樹中不存在度大於2的結點)

五種形態

性質:(見二叉樹的五大性質及證明)

二叉樹的乙個重要的應用是它們在查詢中的使用。假設樹中的每個結點儲存一項資料。使二叉樹成為二叉查詢樹的性質是,對於樹中的每個節點x,它的左子樹中所有項的值小於x中的值,而它的右子樹中所有項的值大於x中的值。

public class binarysearchtree> 

node(anytype element, nodelt, nodert) }

private noderoot; //根節點

public binarysearchtree()

public void makeempty()

public boolean isempty()

}

通過二叉查詢樹有序的性質,能有效節省查詢時的效率,在平均情況下查詢的時間複雜度為o(logn),但在最壞的情況下(此時二叉查詢樹退化成鏈)查詢的時間複雜度會達到o(n)。

/**

* 查詢元素的內部方法,遞迴

* @param x 要查詢的元素

* @param t 子樹的根節點

* @return 是否查詢成功

*/private boolean contains(anytype x, nodet)

在二叉查詢樹的性質中可知,對於樹中的每個節點x,它的左子樹中所有項的值小於x中的值而它的右子樹中所有項的值大於x中的值。這樣使用遞迴的方法可很簡單地實現最大/最小值的查詢。(以下對於最大值和最小值分別使用遞迴和非遞迴的形式實現)

/**

* 查詢樹中最小元素,遞迴

* @param t

* @return

*/private nodefindmin(nodet)

return findmin(t.left);

}/**

* 查詢樹中最大元素,非遞迴實現

* @param t

* @return

*/private nodefindmax(nodet)

}return t;

}

二叉查詢樹插入的實現與查詢相似,即找到對應位置在執行插入操作。

/**

* 將元素插入到二叉查詢樹

* @param x 要查詢的元素

* @param t 子樹的根節點

* @return 插入後的樹的根節點

*/private nodeinsert(anytype x, nodet)

二叉查詢樹節點的刪除有兩種情況:

1.被刪除的節點只有乙個兒子,則該結點可以在其父節點調整自己的鏈後刪除;(若該節點是樹葉的情況等同,此時賦值的值為null)

2.被刪除的節點只有兩個兒子,用其右子樹的最小的資料代替該節點的資料,並遞迴第刪除那個節點。

private noderemove(anytype x, nodet) 

else

t = (t.left != null)?t.left:t.right; //要刪除的節點有乙個孩子或無孩子

return t;

}

中序遍歷首先遍歷左子樹,然後訪問根結點,最後遍歷右子樹。在遍歷左、右子樹時,仍然先遍歷左子樹,再訪問根結點,最後遍歷右子樹。

private void inorder(noderoot)

}

首先訪問根結點然後遍歷左子樹,最後遍歷右子樹。在遍歷左、右子樹時,仍然先訪問根結點,然後遍歷左子樹,最後遍歷右子樹,如果二叉樹為空則返回。

private void preorder(noderoot)

}

後序遍歷首先遍歷左子樹,然後遍歷右子樹,最後訪問根結點,在遍歷左、右子樹時,仍然先遍歷左子樹,然後遍歷右子樹,最後遍歷根結點。

private void postorder(noderoot)

}

設二叉樹的根節點所在層數為1,層序遍歷就是從所在二叉樹的根節點出發,首先訪問第一層的樹根節點,然後從左到右訪問第2層上的節點,接著是第三層的節點,以此類推,自上而下,自左至右逐層訪問樹的結點的過程就是層序遍歷。

/**

* 層次遍歷二叉樹(使用佇列)

* 描述:先將根節點放入佇列中,然後每次都從佇列中取出乙個節點列印,

* 若這個節點有子節點,則將它的子節點放入佇列尾,直到隊列為空

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

1.定義 n n 0 個結點構成的有限集合。當n 0時,稱為空樹 2.對於任一棵非空樹 n 0 它具備以下性質 1 樹中有乙個稱為 根 root 的特殊結點,用 r 表示 2 其餘結點可分為m m 0 個互不相交的有限集t1,t2,其中每個集合本身又是一棵樹,稱為原來樹的子樹。3.樹的一些性質 1 ...

二叉樹 二叉查詢樹

構建二叉樹,判斷是否為二叉查詢樹,遞迴先序遍歷,非遞迴中序遍歷 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 這個就是最完美的樹,顧名思義,所有葉子節點都有相同的深度,並...