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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - 詳解Java二叉排序樹

詳解Java二叉排序樹

2020-03-19 13:11林炳文Evankaka JAVA教程

這篇文章主要介紹了Java二叉排序樹,包括二叉排序樹的定義、二叉排序樹的性質(zhì)、二叉排序樹的插入和查找等,感興趣的小伙伴們可以參考一下

一、二叉排序樹定義
1.二叉排序樹的定義
  二叉排序樹(Binary Sort Tree)又稱二叉查找(搜索)樹(Binary Search Tree)。其定義為:二叉排序樹或者是空樹,或者是滿足如下性質(zhì)的二叉樹:
①若它的左子樹非空,則左子樹上所有結(jié)點的值均小于根結(jié)點的值;
②若它的右子樹非空,則右子樹上所有結(jié)點的值均大于根結(jié)點的值;
③左、右子樹本身又各是一棵二叉排序樹。
上述性質(zhì)簡稱二叉排序樹性質(zhì)(BST性質(zhì)),故二叉排序樹實際上是滿足BST性質(zhì)的二叉樹。

詳解Java二叉排序樹

2.二叉排序樹的性質(zhì)
按中序遍歷二叉排序樹,所得到的中序遍歷序列是一個遞增有序序列。

3.二叉排序樹的插入
在二叉排序樹中插入新結(jié)點,要保證插入后的二叉樹仍符合二叉排序樹的定義。   
插入過程:
若二叉排序樹為空,則待插入結(jié)點*S作為根結(jié)點插入到空樹中;   
當(dāng)非空時,將待插結(jié)點關(guān)鍵字S->key和樹根關(guān)鍵字t->key進行比較,若s->key = t->key,則無須插入,若s->key< t->key,則插入到根的左子樹中,若s->key> t->key,則插入到根的右子樹中。而子樹中的插入過程和在樹中的插入過程相同,如此進行下去,直到把結(jié)點*s作為一個新的樹葉插入到二叉排序樹中,或者直到發(fā)現(xiàn)樹已有相同關(guān)鍵字的結(jié)點為止。

4.二叉排序樹的查找
假定二叉排序樹的根結(jié)點指針為 root ,給定的關(guān)鍵字值為 K ,則查找算法可描述為:
  ① 置初值: q = root ;
  ② 如果 K = q -> key ,則查找成功,算法結(jié)束;
  ③ 否則,如果 K < q -> key ,而且 q 的左子樹非空,則將 q 的左子樹根送 q ,轉(zhuǎn)步驟②;否則,查找失敗,結(jié)束算法;
  ④ 否則,如果 K > q -> key ,而且 q 的右子樹非空,則將 q 的右子樹根送 q ,轉(zhuǎn)步驟②;否則,查找失敗,算法結(jié)束。

5.二叉排序樹的刪除
假設(shè)被刪結(jié)點是*p,其雙親是*f,不失一般性,設(shè)*p是*f的左孩子,下面分三種情況討論:   
⑴ 若結(jié)點*p是葉子結(jié)點,則只需修改其雙親結(jié)點*f的指針即可。   
⑵ 若結(jié)點*p只有左子樹PL或者只有右子樹PR,則只要使PL或PR 成為其雙親結(jié)點的左子樹即可。   
⑶ 若結(jié)點*p的左、右子樹均非空,先找到*p的中序前趨(或后繼)結(jié)點*s(注意*s是*p的左子樹中的最右下的結(jié)點,它的右鏈域為空),然后有兩種做法:① 令*p的左子樹直接鏈到*p的雙親結(jié)點*f的左鏈上,而*p的右子樹鏈到*p的中序前趨結(jié)點*s的右鏈上。② 以*p的中序前趨結(jié)點*s代替*p(即把*s的數(shù)據(jù)復(fù)制到*p中),將*s的左子樹鏈到*s的雙親結(jié)點*q的左(或右)鏈上。
6、二叉樹的遍歷
二叉樹的遍歷有三種方式,如下:
(1)前序遍歷(DLR),首先訪問根結(jié)點,然后遍歷左子樹,最后遍歷右子樹。簡記根-左-右。
(2)中序遍歷(LDR),首先遍歷左子樹,然后訪問根結(jié)點,最后遍歷右子樹。簡記左-根-右。
(3)后序遍歷(LRD),首先遍歷左子樹,然后遍歷右子樹,最后訪問根結(jié)點。簡記左-右-根。

二、代碼編寫
1、樹節(jié)點類的定義0

?
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
package com.lin;
/**
 * 功能概要:
 
 */
public class TreeNode {
   
  public Integer data;
   
  /*該節(jié)點的父節(jié)點*/
  public TreeNode parent;
   
  /*該節(jié)點的左子節(jié)點*/
  public TreeNode left;
   
  /*該節(jié)點的右子節(jié)點*/
  public TreeNode right;
   
  public TreeNode(Integer data) {
    this.data = data;
     
  }
 
  @Override
  public String toString() {
    return "TreeNode [data=" + data + "]";
  }
     
}

2、二叉排序樹的定義

?
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
74
75
76
77
78
79
80
81
82
83
package com.lin;
 
/**
 * 功能概要:排序/平衡二叉樹
 
 */
public class SearchTree {
   
   public TreeNode root;
    
   public long size;
     
  /**
   * 往樹中加節(jié)點 
   * @param data
   * @return Boolean 插入成功返回true
   */
  public Boolean addTreeNode(Integer data) {
 
    if (null == root) {
      root = new TreeNode(data);
      System.out.println("數(shù)據(jù)成功插入到平衡二叉樹中");
      return true;
    }
 
    TreeNode treeNode = new TreeNode(data);// 即將被插入的數(shù)據(jù)
    TreeNode currentNode = root;
    TreeNode parentNode;
 
    while (true) {
      parentNode = currentNode;// 保存父節(jié)點
      // 插入的數(shù)據(jù)比父節(jié)點小
      if (currentNode.data > data) {
        currentNode = currentNode.left;
        // 當(dāng)前父節(jié)點的左子節(jié)點為空
        if (null == currentNode) {
          parentNode.left = treeNode;
          treeNode.parent = parentNode;
          System.out.println("數(shù)據(jù)成功插入到二叉查找樹中");
          size++;
          return true;
        }
        // 插入的數(shù)據(jù)比父節(jié)點大
      } else if (currentNode.data < data) {
        currentNode = currentNode.right;
        // 當(dāng)前父節(jié)點的右子節(jié)點為空
        if (null == currentNode) {
          parentNode.right = treeNode;
          treeNode.parent = parentNode;
          System.out.println("數(shù)據(jù)成功插入到二叉查找樹中");
          size++;
          return true;
        }
      } else {
        System.out.println("輸入數(shù)據(jù)與節(jié)點的數(shù)據(jù)相同");
        return false;
      }
    }    
  }
   
  /**
   * @param data
   * @return TreeNode
   */
  public TreeNode findTreeNode(Integer data){
    if(null == root){
      return null;
    }
    TreeNode current = root;
    while(current != null){
      if(current.data > data){
        current = current.left;
      }else if(current.data < data){
        current = current.right;
      }else {
        return current;
      }
       
    }
    return null;
  }
   
}

這里暫時只放了一個增加和查找的方法
3、前、中、后遍歷

?
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package com.lin;
 
import java.util.Stack;
 
/**
 * 功能概要:
 */
public class TreeOrder {
   
  /**
   * 遞歸實現(xiàn)前序遍歷
   * @author linbingwen
   * @since 2015年8月29日
   * @param treeNode
   */
  public static void preOrderMethodOne(TreeNode treeNode) {
    if (null != treeNode) {
      System.out.print(treeNode.data + " ");
      if (null != treeNode.left) {
        preOrderMethodOne(treeNode.left);
      }
      if (null != treeNode.right) {
        preOrderMethodOne(treeNode.right);
 
      }
    }
  }
 
  /**
   * 循環(huán)實現(xiàn)前序遍歷
   * @param treeNode
   */
  public static void preOrderMethodTwo(TreeNode treeNode) {
    if (null != treeNode) {
      Stack<TreeNode> stack = new Stack<TreeNode>();
      stack.push(treeNode);
      while (!stack.isEmpty()) {
        TreeNode tempNode = stack.pop();
        System.out.print(tempNode.data + " ");
        // 右子節(jié)點不為null,先把右子節(jié)點放進去
        if (null != tempNode.right) {
          stack.push(tempNode.right);
        }
        // 放完右子節(jié)點放左子節(jié)點,下次先取
        if (null != tempNode.left) {
          stack.push(tempNode.left);
        }
      }
    }
  }
   
  /**
   * 遞歸實現(xiàn)中序遍歷
   * @param treeNode
   */
  public static void medOrderMethodOne(TreeNode treeNode){
    if (null != treeNode) {     
      if (null != treeNode.left) {
        medOrderMethodOne(treeNode.left);
      }
      System.out.print(treeNode.data + " ");
      if (null != treeNode.right) {
        medOrderMethodOne(treeNode.right);
      }
    }
     
  }
   
  /**
   * 循環(huán)實現(xiàn)中序遍歷
   * @param treeNode
   */
  public static void medOrderMethodTwo(TreeNode treeNode){  
    Stack<TreeNode> stack = new Stack<TreeNode>(); 
    TreeNode current = treeNode; 
    while (current != null || !stack.isEmpty()) { 
      while(current != null) { 
        stack.push(current); 
        current = current.left; 
      
      if (!stack.isEmpty()) { 
        current = stack.pop(); 
        System.out.print(current.data+" "); 
        current = current.right; 
      
    }    
  }
   
  /**
   * 遞歸實現(xiàn)后序遍歷
   * @param treeNode
   */
  public static void postOrderMethodOne(TreeNode treeNode){    
    if (null != treeNode) {   
      if (null != treeNode.left) {
        postOrderMethodOne(treeNode.left);
      }
      if (null != treeNode.right) {
        postOrderMethodOne(treeNode.right);
      }
      System.out.print(treeNode.data + " ");
    }
     
  }
   
  /**
   * 循環(huán)實現(xiàn)后序遍歷
   * @param treeNode
   */
  public static void postOrderMethodTwo(TreeNode treeNode){
    if (null != treeNode) {
      Stack<TreeNode> stack = new Stack<TreeNode>();
      TreeNode current = treeNode;
      TreeNode rightNode = null;
      while(current != null || !stack.isEmpty()) { 
        while(current != null) { 
          stack.push(current); 
          current = current.left; 
        
        current = stack.pop(); 
        while (current != null && (current.right == null ||current.right == rightNode)) { 
          System.out.print(current.data + " "); 
          rightNode = current; 
          if (stack.isEmpty()){ 
            System.out.println(); 
            return
          
          current = stack.pop(); 
        
        stack.push(current); 
        current = current.right; 
      
       
       
       
    }
  }
   
}

4、使用方法

?
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
package com.lin; 
/**
 * 功能概要:
*/
public class SearchTreeTest {
 
  /**
   * @param args  
   */
  public static void main(String[] args) {
    SearchTree tree = new SearchTree();
    tree.addTreeNode(50);
    tree.addTreeNode(80);
    tree.addTreeNode(20);
    tree.addTreeNode(60);  
    tree.addTreeNode(10);
    tree.addTreeNode(30);
    tree.addTreeNode(70);
    tree.addTreeNode(90);  
    tree.addTreeNode(100);
    tree.addTreeNode(40);
    System.out.println("=============================="+"采用遞歸的前序遍歷開始"+"==============================");
    TreeOrder.preOrderMethodOne(tree.root);
    System.out.println();
    System.out.println("=============================="+"采用循環(huán)的前序遍歷開始"+"==============================");
    TreeOrder.preOrderMethodTwo(tree.root);
    System.out.println();
    System.out.println("=============================="+"采用遞歸的后序遍歷開始"+"==============================");
    TreeOrder.postOrderMethodOne(tree.root);
    System.out.println();
    System.out.println("=============================="+"采用循環(huán)的后序遍歷開始"+"==============================");
    TreeOrder.postOrderMethodTwo(tree.root);
    System.out.println();
    System.out.println("=============================="+"采用遞歸的中序遍歷開始"+"==============================");
    TreeOrder.medOrderMethodOne(tree.root);
    System.out.println();
    System.out.println("=============================="+"采用循環(huán)的中序遍歷開始"+"==============================");
    TreeOrder.medOrderMethodTwo(tree.root);
 
  }
 
}

輸出結(jié)果:

詳解Java二叉排序樹

同樣,進行查找過程如下:

?
1
2
TreeNode node = tree.findTreeNode(100);
System.out.println(node);

詳解Java二叉排序樹

結(jié)果是正確的

以上就是關(guān)于Java二叉排序樹的詳細(xì)介紹,希望對大家的學(xué)習(xí)java程序設(shè)計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 特黄特黄一级片 | 欧美jjvideo| 亚洲国产在线午夜视频无 | 日产乱码卡1卡2卡三免费 | 亚洲xxxxxhd奶水女人 | 视频一区 日韩 | 性欧美videofree中文字幕 | 国产乱子伦一区二区三区 | 亚洲视频一区二区在线观看 | 99热都是精品| 欧美视频一区二区三区在线观看 | 女人麻豆国产香蕉久久精品 | 国产自产2023最新麻豆 | 色综合中文字幕天天在线 | 欧美人畜 | china外卖员gay帮口 | 亚洲国产婷婷俺也色综合 | 日韩视频在线免费 | av排名| 午夜影院免费看 | 国产人人草 | 免费观看视频在线 | 欧洲肥女大肥臀 | 出差被灌醉绝伦的上司日本 | 国产欧美日韩成人 | 欧美日日操| 91制片厂制作传媒免费版樱花 | 久久精品国产只有精品 | 幻女free性俄罗斯第一次摘花 | 国产精品毛片久久久久久久 | 国内亚州视频在线观看 | 午夜欧美精品久久久久久久 | 99视频一区| juliaann大战七个黑人 | 亚洲国产精品嫩草影院永久 | 五月色天在线视频综合观看 | 国产自拍视频网站 | 丝瓜视频在线观看污 | 久久中文字幕免费高清 | 亚洲一卡2卡三卡4卡5卡组 | 国产成人精品午夜在线播放 |