當前位置:首頁 » 編程語言 » java樹的深度

java樹的深度

發布時間: 2022-06-05 00:02:42

1. java中二叉樹的深度怎麼計算

若為空,則其深度為0,否則,其深度等於左子樹和右子樹的深度的最大值加1

2. java如何創建一顆二叉樹

計算機科學中,二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作「左子樹」(left subtree)和「右子樹」(right subtree)。二叉樹常被用作二叉查找樹和二叉堆或是二叉排序樹。

二叉樹的每個結點至多隻有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2的 i -1次方個結點;深度為k的二叉樹至多有2^(k) -1個結點;對任何一棵二叉樹T,如果其終端結點數(即葉子結點數)為n0,度為2的結點數為n2,則n0 = n2 + 1。

樹是由一個或多個結點組成的有限集合,其中:

⒈必有一個特定的稱為根(ROOT)的結點;

二叉樹
⒉剩下的結點被分成n>=0個互不相交的集合T1、T2、......Tn,而且, 這些集合的每一個又都是樹。樹T1、T2、......Tn被稱作根的子樹(Subtree)。

樹的遞歸定義如下:(1)至少有一個結點(稱為根)(2)其它是互不相交的子樹

1.樹的度——也即是寬度,簡單地說,就是結點的分支數。以組成該樹各結點中最大的度作為該樹的度,如上圖的樹,其度為2;樹中度為零的結點稱為葉結點或終端結點。樹中度不為零的結點稱為分枝結點或非終端結點。除根結點外的分枝結點統稱為內部結點。

2.樹的深度——組成該樹各結點的最大層次。

3.森林——指若干棵互不相交的樹的集合,如上圖,去掉根結點A,其原來的二棵子樹T1、T2、T3的集合{T1,T2,T3}就為森林;

4.有序樹——指樹中同層結點從左到右有次序排列,它們之間的次序不能互換,這樣的樹稱為有序樹,否則稱為無序樹。

樹的表示
樹的表示方法有許多,常用的方法是用括弧:先將根結點放入一對圓括弧中,然後把它的子樹由左至右的順序放入括弧中,而對子樹也採用同樣的方法處理;同層子樹與它的根結點用圓括弧括起來,同層子樹之間用逗號隔開,最後用閉括弧括起來。如右圖可寫成如下形式:
二叉樹
(a( b(d,e), c( f( ,g(h,i) ), )))

3. 什麼是樹的遍歷java

樹遍歷方法:有先序遍歷、中序遍歷、後序遍歷以及廣度優先遍歷四種遍歷樹的方法

Demo:


publicclassThreeLinkBinTree<E>{

publicstaticclassTreeNode{

Objectdata;
TreeNodeleft;
TreeNoderight;
TreeNodeparent;

publicTreeNode(){

}

publicTreeNode(Objectdata){
this.data=data;
}

publicTreeNode(Objectdata,TreeNodeleft,TreeNoderight,TreeNodeparent){
this.data=data;
this.left=left;
this.right=right;
this.parent=parent;
}

}

privateTreeNoderoot;

//以默認的構造器創建二叉樹
publicThreeLinkBinTree(){
this.root=newTreeNode();
}

//以指定根元素創建二叉樹
publicThreeLinkBinTree(Edata){
this.root=newTreeNode(data);
}

/**
*為指定節點添加子節點
*
*@paramparent需要添加子節點的父節點的索引
*@paramdata新子節點的數據
*@paramisLeft是否為左節點
*@return新增的節點
*/
publicTreeNodeaddNode(TreeNodeparent,Edata,booleanisLeft){

if(parent==null){
thrownewRuntimeException(parent+"節點為null,無法添加子節點");
}
if(isLeft&&parent.left!=null){
thrownewRuntimeException(parent+"節點已有左子節點,無法添加左子節點");
}
if(!isLeft&&parent.right!=null){
thrownewRuntimeException(parent+"節點已有右子節點,無法添加右子節點");
}

TreeNodenewNode=newTreeNode(data);
if(isLeft){
//讓父節點的left引用指向新節點
parent.left=newNode;
}else{
//讓父節點的left引用指向新節點
parent.right=newNode;
}
//讓新節點的parent引用到parent節點
newNode.parent=parent;
returnnewNode;
}

//判斷二叉樹是否為空
publicbooleanempty(){
//根據元素判斷二叉樹是否為空
returnroot.data==null;
}

//返回根節點
publicTreeNoderoot(){
if(empty()){
thrownewRuntimeException("樹為空,無法訪問根節點");
}
returnroot;
}

//返回指定節點(非根節點)的父節點
publicEparent(TreeNodenode){
if(node==null){
thrownewRuntimeException("節點為null,無法訪問其父節點");
}
return(E)node.parent.data;
}

//返回指定節點(非葉子)的左子節點,當左子節點不存在時返回null
publicEleftChild(TreeNodeparent){
if(parent==null){
thrownewRuntimeException(parent+"節點為null,無法添加子節點");
}
returnparent.left==null?null:(E)parent.left.data;
}

//返回指定節點(非葉子)的右子節點,當右子節點不存在時返回null
publicErightChild(TreeNodeparent){
if(parent==null){
thrownewRuntimeException(parent+"節點為null,無法添加子節點");
}
returnparent.right==null?null:(E)parent.right.data;
}

//返回該二叉樹的深度
publicintdeep(){
//獲取該樹的深度
returndeep(root);
}

//這是一個遞歸方法:每一棵子樹的深度為其所有子樹的最大深度+1
privateintdeep(TreeNodenode){
if(node==null){
return0;
}
//沒有子樹
if(node.left==null&&node.right==null){
return1;
}else{
intleftDeep=deep(node.left);
intrightDeep=deep(node.right);
//記錄其所有左、右子樹中較大的深度
intmax=leftDeep>rightDeep?leftDeep:rightDeep;
//返回其左右子樹中較大的深度+1
returnmax+1;
}
}

//實現先序遍歷
//1、訪問根節點
//2、遞歸遍歷左子樹
//3、遞歸遍歷右子樹
publicList<TreeNode>preIterator(){
returnpreIterator(root);
}

privateList<TreeNode>preIterator(TreeNodenode){

List<TreeNode>list=newArrayList<TreeNode>();
//處理根節點
list.add(node);

//遞歸處理左子樹
if(node.left!=null){
list.addAll(preIterator(node.left));
}

//遞歸處理右子樹
if(node.right!=null){
list.addAll(preIterator(node.right));
}

returnlist;

}

//實現中序遍歷
//1、遞歸遍歷左子樹
//2、訪問根節點
//3、遞歸遍歷右子樹
publicList<TreeNode>inIterator(){
returninIterator(root);
}

privateList<TreeNode>inIterator(TreeNodenode){

List<TreeNode>list=newArrayList<TreeNode>();

//遞歸處理左子樹
if(node.left!=null){
list.addAll(inIterator(node.left));
}

//處理根節點
list.add(node);

//遞歸處理右子樹
if(node.right!=null){
list.addAll(inIterator(node.right));
}

returnlist;

}

//實現後序遍歷
//1、遞歸遍歷左子樹
//2、遞歸遍歷右子樹
//3、訪問根節點
publicList<TreeNode>postIterator(){
returnpostIterator(root);
}

privateList<TreeNode>postIterator(TreeNodenode){

List<TreeNode>list=newArrayList<TreeNode>();

//遞歸處理左子樹
if(node.left!=null){
list.addAll(postIterator(node.left));
}

//遞歸處理右子樹
if(node.right!=null){
list.addAll(postIterator(node.right));
}

//處理根節點
list.add(node);

returnlist;

}

//實現廣度優先遍歷
//廣度優先遍歷又稱為按層遍歷,整個遍歷演算法先遍歷二叉樹的第一層(根節點),再遍歷根節點的兩個子節點(第二層),以此類推
publicList<TreeNode>breadthFirst(){

Queue<TreeNode>queue=newArrayDeque<TreeNode>();
List<TreeNode>list=newArrayList<TreeNode>();
if(root!=null){
//將根元素加入「隊列」
queue.offer(root);
}
while(!queue.isEmpty()){
//將該隊列的「隊尾」的元素添加到List中
list.add(queue.peek());
TreeNodep=queue.poll();
//如果左子節點不為null,將它加入「隊列」
if(p.left!=null){
queue.offer(p.left);
}
//如果右子節點不為null,將它加入「隊列」
if(p.right!=null){
queue.offer(p.right);
}
}
returnlist;
}

}

4. java問題

只要加到比較方法之中就可以
如:比較方法如下
for(int i=0;i<100;i++)
for(int j=i;j<100;j++){
if(array[i]>array[j]){
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
把::
比較次數compare_count、交換次數exchange_count、探測次數probe_count)加到裡面就可以

for(int i=0,compare_count=0;i<100;i++)
for(int j=i;j<100;j++){
if(array[i]>array[j]){
compare_count++;
int temp=array[i];
array[i]=array[j];
array[j]=temp;
exchange_count++;
}
}

就可以了
各種排序方法的綜合比較

一、時間性能

按平均的時間性能來分,有三類排序方法:
時間復雜度為O(nlogn)的方法有:快速排序、堆排序和歸並排序,其中以快速排序為最好;

時間復雜度為O(n2)的有:直接插入排序、起泡排序和簡單選擇排序,其中以直接插入為最好,特別是對那些對關鍵字近似有序的記錄序列尤為如此;

時間復雜度為O(n)的排序方法只有,基數排序。

當待排記錄序列按關鍵字順序有序時,直接插入排序和起泡排序能達到O(n)的時間復雜度;而對於快速排序而言,這是最不好的情況,此時的時間性能蛻化為O(n2),因此是應該盡量避免的情況。
簡單選擇排序、堆排序和歸並排序的時間性能不隨記錄序列中關鍵字的分布而改變。
二、空間性能

指的是排序過程中所需的輔助空間大小。

1. 所有的簡單排序方法(包括:直接插入、起泡和簡單選擇)和堆排序的空間復雜度為O(1);

2. 快速排序為O(logn ),為棧所需的輔助空間;

3. 歸並排序所需輔助空間最多,其空間復雜度為O(n );

4.鏈式基數排序需附設隊列首尾指針,則空間復雜度為O(rd )。

三、排序方法的穩定性能

1. 穩定的排序方法指的是,對於兩個關鍵字相等的記錄,它們在序列中的相對位置,在排序之前和經過排序之後,沒有改變。

2. 當對多關鍵字的記錄序列進行LSD方法排序時,必須採用穩定的排序方法。

3. 對於不穩定的排序方法,只要能舉出一個實例說明即可。

4. 快速排序和堆排序是不穩定的排序方法。

四、關於「排序方法的時間復雜度的下限」

本章討論的各種排序方法,除基數排序外,其它方法都是基於「比較關鍵字」進行排序的排序方法,可以證明,這類排序法可能達到的最快的時間復雜度為O(n logn )。(基數排序不是基於「比較關鍵字」的排序方法,所以它不受這個限制)。

可以用一棵判定樹來描述這類基於「比較關鍵字」進行排序的排序方法。

例如,對三個關鍵字進行排序的判定樹如下:

描述排序的判定樹有兩個特點:

1.樹上的每一次「比較」都是必要的;

2.樹上的葉子結點包含所有可能情況。

則由上圖所示「判定樹的深度為4」可以推出「至多進行三次比較」即可完成對三個關鍵字的排序。反過來說,由此判定樹可見,考慮最壞情況,「至少要進行三次比較」才能完成對三個關鍵字的排序。

對三個關鍵字進行排序的判定樹深度是唯一的。即無論按什麼先後順序去進行比較,所得判定樹的深度都是3。

當關鍵字的個數超過3之後,不同的排序方法其判定樹的深度不同。例如,對4個關鍵字進行排序時,直接插入的判定樹的深度為6, 而折半插入的判定樹的深度為5。

可以證明,對4個關鍵字進行排序,至少需進行5次比較。因為,4個關鍵字排序的結果有4!=24種可能,即排序的判定樹上必須有24個葉子結點,其深度的最小值為6。

一般情況下,對n個關鍵字進行排序,可能得到的結果有n! 種,由於含n! 個葉子結點的二叉樹的深度不小於 , 則對n個關鍵字進行排序的比較次數至少是

。利用斯蒂林近似公式

所以,基於「比較關鍵字」進行排序的排序方法,可能達到的最快的時間復雜度為O(n logn )。

快速排序是對冒泡排序的一種改進。它的基本思想是:通過一躺排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一不部分的所有數據都要小,然後再按次方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

假設要排序的數組是A[1]……A[N],首先任意選取一個數據(通常選用第一個數據)作為關鍵數據,然後將所有比它的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一躺快速排序。一躺快速排序的演算法是:

1)、設置兩個變數I、J,排序開始的時候I:=1,J:=N;

2)以第一個數組元素作為關鍵數據,賦值給X,即X:=A[1];

3)、從J開始向前搜索,即由後開始向前搜索(J:=J-1),找到第一個小於X的值,兩者交換;

4)、從I開始向後搜索,即由前開始向後搜索(I:=I+1),找到第一個大於X的值,兩者交換;

5)、重復第3、4步,直到I=J;

例如:待排序的數組A的值分別是:(初始關鍵數據X:=49)

A[1] A[2] A[3] A[4] A[5] A[6] A[7]:

49 38 65 97 76 13 27

進行第一次交換後: 27 38 65 97 76 13 49

( 按照演算法的第三步從後面開始找

進行第二次交換後: 27 38 49 97 76 13 65

( 按照演算法的第四步從前面開始找>X的值,65>49,兩者交換,此時I:=3 )

進行第三次交換後: 27 38 13 97 76 49 65

( 按照演算法的第五步將又一次執行演算法的第三步從後開始找

進行第四次交換後: 27 38 13 49 76 97 65

( 按照演算法的第四步從前面開始找大於X的值,97>49,兩者交換,此時J:=4 )

此時再執行第三不的時候就發現I=J,從而結束一躺快速排序,那麼經過一躺快速排序之後的結果是:27 38 13 49 76 97 65,即所以大於49的數全部在49的後面,所以小於49的數全部在49的前面。

快速排序就是遞歸調用此過程——在以49為中點分割這個數據序列,分別對前面一部分和後面一部分進行類似的快速排序,從而完成全部數據序列的快速排序,最後把此數據序列變成一個有序的序列,根據這種思想對於上述數組A的快速排序的全過程如圖6所示:

初始狀態 {49 38 65 97 76 13 27}

進行一次快速排序之後劃分為 {27 38 13} 49 {76 97 65}

分別對前後兩部分進行快速排序 {13} 27 {38}

結束 結束 {49 65} 76 {97}

49 {65} 結束

結束

圖6 快速排序全過程

1)、設有N(假設N=10)個數,存放在S數組中;
2)、在S[1。。N]中任取一個元素作為比較基準,例如取T=S[1],起目的就是在定出T應在排序結果中的位置K,這個K的位置在:S[1。。K-1]<=S[K]<=S[K+1..N],即在S[K]以前的數都小於S[K],在S[K]以後的數都大於S[K];

3)、利用分治思想(即大化小的策略)可進一步對S[1。。K-1]和S[K+1。。N]兩組數據再進行快速排序直到分組對象只有一個數據為止。 1 2 3 4 5 6 7 8 9 10

如具體數據如下,那麼第一躺快速排序的過程是:

數組下標:

45 36 18 53 72 30 48 93 15 36

5) 36 36 18 15 30 45 48 93 72 534) 36 36 18 15 45 30 48 93 72 533) 36 36 18 15 72 30 48 93 45 532) 36 36 18 45 72 30 48 93 15 53

program kuaisu(input,output);
const n=10;
var
s:array[1..10] of integer;
k,l,m:integer;

procere qsort(lx,rx:integer);
var
I,j,t:integer;
Begin
I:lx;j:rx;t:s[I];
Repeat
While (s[j]>t) and (j>I) do
Begin
k:=k+1;
j:=j-1
end;
if I<j then
begin
s[I]:=s[j];I:=I+1;l:=l+1;
while (s[I]<t) and (I<j) do
begin
k:=k+1;
I:=I+1
End;
If I<j then
begin
S[j]:=s[I];j:=j-1;l:=l+1;
End;
End;
Until I=j;
S[I]:=t;I:=I+1;j:=j-1;l:=l+1;
If lx<j then qsort(lx,j);
If I<rx then qsort(I,rx)
End;{過程qsort結束}

Begin
Writeln('input 10 integer num:');
For m:=1 to n do read(s[m]);
K:=0;l:=0;
Qsort(l,n);
Writeln('排序後結果是:');
For m:=1 to n do write(s[m]:4)
End.

通過一躺排序將45放到應該放的位置K,這里K=6,那麼再對S[1。。5]和S[6。。10]分別進行快速排序。程序代碼如下:<49,兩者交換,此時J:=6>

5. java,求二叉樹的深度的演算法實現

用遞歸很簡單了。

BTNode類就自己定義吧,屬性為名字,和左右孩子以及set、get方法

前序遍歷:
protected static void preorder(BTNode node) {
if (node != null) {
visit(node);//隨便寫點列印p的名字之類的語句
preorder(node.getLeft());
preorder(node.getRight());
}
}
中序:
protected static void inorder(BTNode node) {
if (node != null) {
inorder(node.getLeft());
visit(node);
inorder(node.getRight());
}
}
後序:
protected static void postorder(BTNode node) {
if (node != null) {
postorder(node.getLeft());
postorder(node.getRight());
visit(node);
}
}
非遞歸的就麻煩了,得用到棧。我就偷個懶不做了...

6. java二叉樹遍歷問題

二叉樹具有以下重要性質:
性質1 二叉樹第i層上的結點數目最多為2i-1(i≥1)。
證明:用數學歸納法證明:
歸納基礎:i=1時,有2i-1=20=1。因為第1層上只有一個根結點,所以命題成立。
歸納假設:假設對所有的j(1≤j<i)命題成立,即第j層上至多有2j-1個結點,證明j=i時命題亦成立。
歸納步驟:根據歸納假設,第i-1層上至多有2i-2個結點。由於二叉樹的每個結點至多有兩個孩子,故第i層上的結點數至多是第i-1層上的最大結點數的2倍。即j=i時,該層上至多有2×2i-2=2i-1個結點,故命題成立。

性質2 深度為k的二叉樹至多有2k-1個結點(k≥1)。
證明:在具有相同深度的二叉樹中,僅當每一層都含有最大結點數時,其樹中結點數最多。因此利用性質1可得,深度為k的二叉樹的結點數至多為:
20+21+…+2k-1=2k-1
故命題正確。

性質3 在任意-棵二叉樹中,若終端結點的個數為n0,度為2的結點數為n2,則no=n2+1。
證明:因為二叉樹中所有結點的度數均不大於2,所以結點總數(記為n)應等於0度結點數、1度結點(記為n1)和2度結點數之和:
n=no+n1+n2 (式子1)
另一方面,1度結點有一個孩子,2度結點有兩個孩子,故二叉樹中孩子結點總數是:
nl+2n2
樹中只有根結點不是任何結點的孩子,故二叉樹中的結點總數又可表示為:
n=n1+2n2+1 (式子2)
由式子1和式子2得到:
no=n2+1

滿二叉樹和完全二叉樹是二叉樹的兩種特殊情形。
1、滿二叉樹(FullBinaryTree)
一棵深度為k且有2k-1個結點的二又樹稱為滿二叉樹。
滿二叉樹的特點:
(1) 每一層上的結點數都達到最大值。即對給定的高度,它是具有最多結點數的二叉樹。
(2) 滿二叉樹中不存在度數為1的結點,每個分支結點均有兩棵高度相同的子樹,且樹葉都在最下一層上。
圖(a)是一個深度為4的滿二叉樹。

2、完全二叉樹(Complete BinaryTree)
若一棵二叉樹至多隻有最下面的兩層上結點的度數可以小於2,並且最下一層上的結點都集中在該層最左邊的若干位置上,則此二叉樹稱為完全二叉樹。
特點:
(1) 滿二叉樹是完全二叉樹,完全二叉樹不一定是滿二叉樹。
(2) 在滿二叉樹的最下一層上,從最右邊開始連續刪去若干結點後得到的二叉樹仍然是一棵完全二叉樹。
(3) 在完全二叉樹中,若某個結點沒有左孩子,則它一定沒有右孩子,即該結點必是葉結點。
如圖(c)中,結點F沒有左孩子而有右孩子L,故它不是一棵完全二叉樹。
圖(b)是一棵完全二叉樹。

性質4 具有n個結點的完全二叉樹的深度為

證明:設所求完全二叉樹的深度為k。由完全二叉樹定義可得:
深度為k得完全二叉樹的前k-1層是深度為k-1的滿二叉樹,一共有2k-1-1個結點。
由於完全二叉樹深度為k,故第k層上還有若干個結點,因此該完全二叉樹的結點個數:
n>2k-1-1。
另一方面,由性質2可得:
n≤2k-1,
即:2k-1-l<n≤2k-1
由此可推出:2k-1≤n<2k,取對數後有:
k-1≤lgn<k
又因k-1和k是相鄰的兩個整數,故有
,
由此即得:

注意:
的證明

7. 在線等,計算機高手,java深度搜索樹代碼

有一本書,是講JAVA數據結構的,裡面有很多樹的講解和例子,二叉樹什麼的,還有樹的遍歷,都有例子,建議去看一下

熱點內容
傳奇裝備強化腳本 發布:2024-04-28 18:34:29 瀏覽:328
QQ如何撤銷以儲存的密碼 發布:2024-04-28 18:32:13 瀏覽:321
ttsandroid中文 發布:2024-04-28 18:30:38 瀏覽:766
修改密碼後為什麼連接不了 發布:2024-04-28 18:16:48 瀏覽:743
cfm安卓轉蘋果在哪個買 發布:2024-04-28 18:07:15 瀏覽:161
編譯器錯誤都是什麼意思 發布:2024-04-28 17:31:30 瀏覽:74
伺服器不能復制粘貼到本機是怎麼回事 發布:2024-04-28 17:24:50 瀏覽:15
房產中介管理系統源碼 發布:2024-04-28 17:23:53 瀏覽:77
文件傳輸java 發布:2024-04-28 17:19:24 瀏覽:195
存儲過程中的is 發布:2024-04-28 17:13:45 瀏覽:406