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

服務(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è)計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 狠狠综合网 | 日韩一 | 免费看男女污污完整版 | 国产性视频 | 亚洲国产美女精品久久久久 | 狠狠做五月深爱婷婷天天综合 | www.爱情岛论坛 | 亚洲欧美专区精品伊人久久 | 成人久久伊人精品伊人 | 私人影院在线播放 | 门房秦大爷小说 | 无码日韩精品一区二区免费 | 91搞搞| crdy在线看亚洲 | 日本精品久久久久中文字幕 1 | 欧美3p大片在线观看完整版 | 日本xxx在线观看免费播放 | 日本国产高清色www视频在线 | 国产精品日韩欧美一区二区三区 | free性丰满hd性欧美厨房 | 亚洲v日韩v欧美在线观看 | 无码人妻视频又大又粗欧美 | 亚洲AV综合99一二三四区 | 国产欧美日韩精品高清二区综合区 | 日日视频 | 9久re热视频这里只有精品 | 国产免费不卡视频 | china外卖员gay国产xnxx | 互换娇妻爽文100系列小说 | 日本精品中文字幕在线播放 | 美女撒尿无遮挡免费中国 | 国产成人亚洲精品一区二区在线看 | 脱jk裙的美女露小内内无遮挡 | 岛国a香蕉片不卡在线观看 荡女淫春2古装 | 精品欧美一区二区三区久久久 | 2020年最新国产精品视频免费 | 成版人快猫永久破解版 | 国产午夜亚洲精品理论片不卡 | 成人aqq| 女老板用丝袜脚夹我好爽 | 午夜欧美福利视频 |