一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java數據結構與算法之樹(動力節點java學院整理)

Java數據結構與算法之樹(動力節點java學院整理)

2020-09-09 13:30動力節點 Java教程

這篇文章主要介紹了Java數據結構與算法之樹的相關知識,最主要的是二叉樹中的二叉搜索樹,需要的朋友可以參考下

為什么使用樹:

   樹結合了兩種數據結構的有點:一種是有序數組,樹在查找數據項的速度和在有序數組中查找一樣快;另一種是鏈表,樹在插入數據和刪除數據項的速度和鏈表一樣。既然這樣,就要好好去學了....
(最主要討論的是二叉樹中的二叉搜索樹,即一個節點的左子節點關鍵值小于這個節點,右子節點的關鍵值大于這個節點)

Java數據結構與算法之樹(動力節點java學院整理)

設計前的思考:

樹——>元素(節點)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class node
{
 public int idata ;
 public float fdata ;
 public node left ;
 public node right ;
 //方法
 public node(int idata,float fdata){}
 public void displaynode(){}
}
class tree
{
 node root ;//樹根
 //方法
 public void insert(){}
 public void displaytree(){}
 public void find(){}
 public void delete(){}
}

插入數據:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//插入子節點
public void insert(int idata ,float fdata)
{
node newnode = new node(idata,fdata) ;
if(root == null)
root = newnode ;
else
{
node current = root ;
node parent ;
while(true)//尋找插入的位置
{
parent = current ;
if(idata<current.idata)
{
current = current.left ;
if(current == null)
{
parent.left = newnode ;
return ;
}
}
else
{
current =current.right ;
if(current == null)
{
parent.right = newnode ;
return ;
}
}
}
}
}

遍歷樹:

?
1
2
3
4
5
6
7
8
9
10
//中序遍歷方法
 public void inorder(node localroot)
 {
 if(localroot != null)
 {
 inorder(localroot.left) ;//調用自身來遍歷左子樹
 localroot.displaynode() ;//訪問這個節點
 inorder(localroot.right) ;//調用自身來遍歷右子樹
 }
 }

查找某個節點:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//查找某個節點
 public node find(int idata)
 {
 node current = root ;
 while(current.idata != idata)
 {
 if(current.idata<idata)
 current = current.right ;
 else
 current = current.left ;
 if(current == null)
 return null ;
 }
 return current ;
 }

查找樹中關鍵字的最大值和最小值:

最大值:不斷地尋找右子節點

最小值:不斷地尋找左子節點

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//查找關鍵字最小的節點
 public node findminnode()
 {
 node current , last ;
 last = null ;
 current = root ;
 if(current.left == null)
 return current ;
 else
 {
 while(current != null)
 {
 last = current ;
 current = current.left ;
 }
 return last ;
 }
 }

 刪除某個節點:

 思考:

1).先找到要刪除的節點:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public boolean delete(int key)
 {
 //先找到需要刪除的節點
 node current = root ;
 node parent = root ;
 boolean isleftchild = false ;
 while(current.idata != key)//顯然,當current.idata == key 時,current 就是要找的節點
 {
 parent = current ;
 if(key < current.idata)
 {
 isleftchild = true ;
 current = current.left ;
 }
 else
 {
 isleftchild = false ;
 current = current.right ;
 }
 if(current == null)//找不到key時返回false
 return false ;
 }
 //continue ........
 }

2).再考慮要刪除的節點是怎樣的節點,經分析,有三種情況:葉節點、有一個節點的節點、有兩個節點的節點

a).如果刪除的是一個葉子節點,直接刪除即可

Java數據結構與算法之樹(動力節點java學院整理)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//接上................
 //分情況考慮刪除的節點
 //刪除的節點為葉節點時
 if(current.left == null && current.right == null)
 {
 if(current == root)
 root = null ;
 else
 if(isleftchild)
 parent.left = null ;
 else
 parent.right = null ;
 }
//continue...........

b).如果刪除的節點有一個節點時:分兩種情況,刪除的節點只有一個左子節點,或者只有一個右子節點

Java數據結構與算法之樹(動力節點java學院整理)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//接上.......
//刪除的節點有一個子節點
 else
 if(current.right == null)//刪除的節點只有一個左子節點時
 {
 if(current == root)//要刪除的節點為根節點
 root = current.left ;
 else
 if(isleftchild)//要刪除的節點是一個左子節點
 parent.left = current.left ;
 else
 parent.right = current.left ;//要刪除的節點是一個右子節點
 }
 else
 if(current.left == null)//刪除的節點只有一個右子節點時
 {
 if(current == root)//要刪除的節點為根節點
 root = current.right ;
 else
 if(isleftchild)//要刪除的節點是一個左子節點
 parent.left = current.right ;
 else
 parent.right = current.right ;//要刪除的節點是一個右子節點
 }
//continue.......

c).如果刪除的節點有兩個節點時:

Java數據結構與算法之樹(動力節點java學院整理)

這種情況就比較復雜,需要去尋找一個節點去替代要刪除的節點。這個節點應該是什么節點呢?

據書本介紹,最合適的節點是后繼節點,即比要刪除的節點的關鍵值次高的節點是它的后繼節點。

說得簡單一些,后繼節點就是比要刪除的節點的關鍵值要大的節點集合中的最小值。

以上面的為例,40的后繼節點為74,10的后繼節點是13,19的后繼節點時26

以下是尋找后繼節點的代碼: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//返回后繼節點
private node getsuccessor(node delnode)
{
node successorparent = delnode ;//后繼節點的父節點
node successor = delnode ;//后繼節點
node current = delnode.right ;//移動到位置節點位置
while(current != null)
{
successorparent = successor ;
successor = current ;
current = current.left ;
}
if(successor != delnode.right)
{
successorparent.left = successor.right ;
successor.right = delnode.right ;
}
return successor ;
}

 找到了后繼節點,接著就要討論如何用后繼節點替代藥刪除的節點

a)如果后繼節點是剛好是要刪除節點的右子節點(此時可以知道,這個右子節點沒有左子點,如果有,就不該這個右子節點為后繼節點)

Java數據結構與算法之樹(動力節點java學院整理)

Java數據結構與算法之樹(動力節點java學院整理)

?
1
2
3
4
5
6
//要刪除的節點為左子節點時
parent.left = successor ;
successor.left = current.left ;
//要刪除的節點是右子節點時
parent.right = successor ;
successor.left = current.left ;

b)如果后繼節點為要刪除節點的右子節點的左后代:

Java數據結構與算法之樹(動力節點java學院整理)

Java數據結構與算法之樹(動力節點java學院整理)

?
1
2
3
4
5
6
7
8
9
10
//假如要刪除的節點為右子節點
successorparent.left = successor.right ;//第一步
successor.right = current.right ;//第二步
parent.right = successor ;
successor.left = current.left ;
//假設要刪除的節點為左子節點
successorparent.left = successor.right ;
successor.right = current.right ;
parent.left = successor ;
successor.left = current.left ;

注意:第一步和第二步在getsuccessor()方法的最后的if語句中完成

以下是刪除的節點有連個節點的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//接上
 //刪除的節點有兩個子節點
 else
 {
 node successor = getsuccessor(current) ;//找到后繼節點
 if(current == root)
 root = successor ;
 else
 if(isleftchild)
 parent.left = successor ;
 else
 parent.right = successor ;
 successor.left = current.left ;
 }
 //continue....

綜合上述,給出delete()方法的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//刪除某個節點
 public boolean delete(int key)
 {
 //先找到需要刪除的節點
 node current = root ;
 node parent = root ;
 boolean isleftchild = false ;
 while(current.idata != key)//顯然,當current.idata == key 時,current 就是要找的節點
 {
 parent = current ;
 if(key < current.idata)
 {
 isleftchild = true ;
 current = current.left ;
 }
 else
 {
 isleftchild = false ;
 current = current.right ;
 }
 if(current == null)//找不到key時返回false
 return false ;
 }
 //分情況考慮刪除的節點
 //刪除的節點為葉節點時
 if(current.left == null && current.right == null)
 {
 if(current == root)
 root = null ;
 else
 if(isleftchild)
 parent.left = null ;
 else
 parent.right = null ;
 }
 //刪除的節點有一個子節點
 else
 if(current.right == null)//刪除的節點只有一個左子節點時
 {
 if(current == root)//要刪除的節點為根節點
 root = current.left ;
 else
 if(isleftchild)//要刪除的節點是一個左子節點
 parent.left = current.left ;
 else
 parent.right = current.left ;//要刪除的節點是一個右子節點
 }
 else
 if(current.left == null)//刪除的節點只有一個右子節點時
 {
 if(current == root)//要刪除的節點為根節點
 root = current.right ;
 else
 if(isleftchild)//要刪除的節點是一個左子節點
 parent.left = current.right ;
 else
 parent.right = current.right ;//要刪除的節點是一個右子節點
 }
 //刪除的節點有兩個子節點
 else
 {
 node successor = getsuccessor(current) ;//找到后繼節點
 if(current == root)
 root = successor ;
 else
 if(isleftchild)
 parent.left = successor ;
 else
 parent.right = successor ;
 successor.left = current.left ;
 }
 return true ;
 }

進一步考慮:

刪除那么復雜,那刪除是必要的嗎?我們可以給每個節點定義一個標志,該標志用于記錄該節點是否已經刪除了,顯示樹時,先判斷該節點是否已經刪除,如果沒有,則顯示。

這樣的結果是,節點其實是沒有刪除的,這樣顯然逃避責任了。當樹中沒有那么多的刪除操作時,這也不失為一種好方法,例如:

已經離職的員工的檔案要永久地保存在員工的記錄中。

以上所述是小編給大家介紹的java數據結構與算法之樹(動力節點java學院整理),希望對大家有所幫助

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 水岛津实在线 | 欧美亚洲国产一区二区三区 | 4虎影视国产在线观看精品 4s4s4s4s色大众影视 | v视影院 | 四虎在线永久免费视频网站 | 蜜桃视频在线观看www | 免费视频 久久久 | free性日本 | 欧美成人精品福利网站 | 成人性用品 | 精品午夜久久福利大片免费 | 黑人巨大videosjapan高清 黑人好大 | 胖女性大bbbbbb | 国产亚洲精品美女 | 日韩在线二区全免费 | 九九99热| 高清视频在线观看+免费 | 久久视频在线视频 | 狠狠五月天中文字幕 | 久久中文字幕乱码免费 | 亚洲无限观看 | 34g污奶跳舞| 色444| 日本精品人妖shemale人妖 | 视频一区在线免费观看 | 超强台风免费观看完整版视频 | 久久精品国产久精国产果冻传媒 | 欧美一区二区三区大片 | 天天插伊人 | 国产午夜免费视频 | 腿交hd | 日韩在线a视频免费播放 | 午夜精品久久久久久久2023 | 欧美区一区 | 四虎永久在线精品波多野结衣 | 成人网子| 嫩草成人影院 | 国产色综合久久五月色婷婷中文 | 美女被到爽流动漫 | 国产在线播放一区 | 俄罗斯引擎首页进入 |