日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java二叉树的构建与遍历

發(fā)布時間:2025/3/20 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java二叉树的构建与遍历 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、二叉排序樹定義

1.二叉排序樹的定義

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

上述性質簡稱二叉排序樹性質(BST性質),故二叉排序樹實際上是滿足BST性質的二叉樹。



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

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

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

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

6、二叉樹的遍歷

二叉樹的遍歷有三種方式,如下:
(1)前序遍歷(DLR),首先訪問根結點,然后遍歷左子樹,最后遍歷右子樹。簡記根-左-右。
(2)中序遍歷(LDR),首先遍歷左子樹,然后訪問根結點,最后遍歷右子樹。簡記左-根-右。
(3)后序遍歷(LRD),首先遍歷左子樹,然后遍歷右子樹,最后訪問根結點。簡記左-右-根。?


二、代碼編寫

1、樹節(jié)點類的定義

[java]view plaincopy
  • package?com.lin;??
  • /**?
  • ?*?功能概要:?
  • ?*??
  • ?*?@author?linbingwen?
  • ?*?@since??2015年8月29日??
  • ?*/??
  • 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、二叉排序樹的定義

    [java]view plaincopy
  • package?com.lin;??
  • ??
  • /**?
  • ?*?功能概要:排序/平衡二叉樹?
  • ?*??
  • ?*?@author?linbingwen?
  • ?*?@since??2015年8月29日??
  • ?*/??
  • public?class?SearchTree?{??
  • ??????
  • ?????public?TreeNode?root;??
  • ???????
  • ?????public?long?size;??
  • ??????????
  • ????/**?
  • ?????*?往樹中加節(jié)點?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@param?data?
  • ?????*?@return?Boolean?插入成功返回true?
  • ?????*/??
  • ????public?Boolean?addTreeNode(Integer?data)?{??
  • ??
  • ????????if?(null?==?root)?{??
  • ????????????root?=?new?TreeNode(data);??
  • ????????????System.out.println("數據成功插入到平衡二叉樹中");??
  • ????????????return?true;??
  • ????????}??
  • ??
  • ????????TreeNode?treeNode?=?new?TreeNode(data);//?即將被插入的數據??
  • ????????TreeNode?currentNode?=?root;??
  • ????????TreeNode?parentNode;??
  • ??
  • ????????while?(true)?{??
  • ????????????parentNode?=?currentNode;//?保存父節(jié)點??
  • ????????????//?插入的數據比父節(jié)點小??
  • ????????????if?(currentNode.data?>?data)?{??
  • ????????????????currentNode?=?currentNode.left;??
  • ????????????????//?當前父節(jié)點的左子節(jié)點為空??
  • ????????????????if?(null?==?currentNode)?{??
  • ????????????????????parentNode.left?=?treeNode;??
  • ????????????????????treeNode.parent?=?parentNode;??
  • ????????????????????System.out.println("數據成功插入到二叉查找樹中");??
  • ????????????????????size++;??
  • ????????????????????return?true;??
  • ????????????????}??
  • ????????????????//?插入的數據比父節(jié)點大??
  • ????????????}?else?if?(currentNode.data?<?data)?{??
  • ????????????????currentNode?=?currentNode.right;??
  • ????????????????//?當前父節(jié)點的右子節(jié)點為空??
  • ????????????????if?(null?==?currentNode)?{??
  • ????????????????????parentNode.right?=?treeNode;??
  • ????????????????????treeNode.parent?=?parentNode;??
  • ????????????????????System.out.println("數據成功插入到二叉查找樹中");??
  • ????????????????????size++;??
  • ????????????????????return?true;??
  • ????????????????}??
  • ????????????}?else?{??
  • ????????????????System.out.println("輸入數據與節(jié)點的數據相同");??
  • ????????????????return?false;??
  • ????????????}??
  • ????????}?????????
  • ????}??
  • ??????
  • ????/**?
  • ?????*?查找數據?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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、前、中、后遍歷

    [java]view plaincopy
  • package?com.lin;??
  • ??
  • import?java.util.Stack;??
  • ??
  • /**?
  • ?*?功能概要:?
  • ?*??
  • ?*?@author?linbingwen?
  • ?*?@since??2015年8月29日??
  • ?*/??
  • 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)前序遍歷?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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)中序遍歷?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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)中序遍歷?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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)后序遍歷?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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)后序遍歷?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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、使用方法

    [java]view plaincopy
  • package?com.lin;??
  • ??
  • /**?
  • ?*?功能概要:?
  • ?*??
  • ?*?@author?linbingwen?
  • ?*?@since??2015年8月29日??
  • ?*/??
  • public?class?SearchTreeTest?{??
  • ??
  • ????/**?
  • ?????*?@author?linbingwen?
  • ?????*?@since??2015年8月29日??
  • ?????*?@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);??
  • ??
  • ????}??
  • ??
  • }??

  • 輸出結果:



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

    [java]view plaincopy
  • TreeNode?node?=?tree.findTreeNode(100);??
  • System.out.println(node);??


  • 結果是正確的



    原文鏈接:http://blog.csdn.net/evankaka/article/details/48088241

    總結

    以上是生活随笔為你收集整理的Java二叉树的构建与遍历的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。