java數(shù)據(jù)結(jié)構(gòu)(四)

關(guān)于樹的基本概念可以查看此篇文章樹鳖枕、堆、集合

1桨螺、一般樹的實現(xiàn):

樹結(jié)構(gòu)可以由遞歸實現(xiàn)宾符,也可以由鏈表實現(xiàn):
鏈表實現(xiàn)的單個節(jié)點的表示方法:

class TreeNode{
    Object element;  //節(jié)點的值
    TreeNode firstChild; //該節(jié)點的第一個子節(jié)點
    TreeNode nextSibling; //下一個兄弟節(jié)點
}

樹的遍歷:分為前序遍歷、后續(xù)遍歷灭翔,二叉樹還有一種特殊的遍歷方法(中序遍歷)魏烫;
前序遍歷:及對節(jié)點的處理,先于其子節(jié)點進行肝箱,其時間復雜度為O(n);
后序遍歷:及對節(jié)點的處理哄褒,晚于其子節(jié)點進行,其時間復雜度為O(n);
[圖片上傳失敗...(image-754579-1509972359621)]

前序遍歷為:A-B-D-#-#-#-C-E-#-#-#

后序遍歷為:#-#-D-#-B-#-#-E-#-C-A

2煌张、二叉樹的實現(xiàn):

二叉樹是一顆樹呐赡,其每個節(jié)點都不能有多于兩個的兒子;

其單個節(jié)點為:

    private static class BinaryNode<T>{
        T element;
        BinaryNode<T> leftBinaryNode;
        BinaryNode<T> rightBinaryNode;
        
        BinaryNode(T element){
            this.element=element;
        }

        public BinaryNode(T element, BinaryNode<T> leftBinaryNode, BinaryNode<T> rightBinaryNode) {
            this.element = element;
            this.leftBinaryNode = leftBinaryNode;
            this.rightBinaryNode = rightBinaryNode;
        }
        
    }

二叉搜索樹的實現(xiàn):


package tree;

import com.sun.jmx.remote.internal.ArrayQueue;

import java.nio.BufferUnderflowException;
import java.util.Queue;

public class myBinaryTree<T extends Comparable<? super T>> {
    private BinaryNode<T> root;
    public myBinaryTree(){
        root=null;
    }
    public boolean isEmpty(){
        return root==null;
    }
    public void makeEmpty(){
        root=null;
    }
    public boolean contains(T item){
        return contains(item,root);
    }

    private boolean contains(T item,BinaryNode<T> t){
        if(t==null){
            return false;
        }
        int compareValue=item.compareTo(t.element);
        if(compareValue<0){
            return contains(item,t.leftBinaryNode);
        }
        else if(compareValue>0){
            return contains(item,t.rightBinaryNode);
        }
        else {
            return true;
        }
    }


    public T findMin(){
        if(isEmpty())
            throw new BufferUnderflowException();
        return findMin(root).element;
    }
    private BinaryNode<T> findMin(BinaryNode<T> t){
        if(t==null){
            return null;
        }
        while (t.leftBinaryNode!=null){
            t=t.leftBinaryNode;
        }
        return t;
    }


    public T findMax(){
        if(isEmpty())
            throw new BufferUnderflowException();
        return findMax(root).element;
    }
    private BinaryNode<T> findMax(BinaryNode<T> t){
        if(t==null){
            return null;
        }
        while (t.rightBinaryNode!=null){
            t=t.rightBinaryNode;
        }
        return t;
    }

    public void insert(T item){
        root=insert(item,root);
    }
    private BinaryNode<T> insert(T item,BinaryNode<T> t){
        if(t==null){
            return new BinaryNode<T>(item,null,null);
        }
        int compareValue=item.compareTo(t.element);
        if(compareValue<0){
            t.leftBinaryNode=insert(item,t.leftBinaryNode);
        }
        else if(compareValue>0){
            t.rightBinaryNode=insert(item,t.rightBinaryNode);
        }
        else{
            ;
        }

        return t;
    }

    public int height(){
        if(isEmpty()){
            return 0;
        }
        else
            return height(root);
    }
    private int height(BinaryNode<T> t){
        if(t==null){
            return 0;
        }
        else
            return 1+Math.max(height(t.rightBinaryNode),height(t.leftBinaryNode));
    }


    public void printTreeNodeLast(){ //后序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTreeNodeLast(root);
        }
    }
    private void printTreeNodeLast(BinaryNode<T> t){
        if (t!=null){
            printTreeNodeLast(t.leftBinaryNode);
            printTreeNodeLast(t.rightBinaryNode);
            System.out.println(t.element);
        }
    }


    public void printTreeNodeFirst(){ //先序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTreeNodeFirst(root);
        }
    }
    private void printTreeNodeFirst(BinaryNode<T> t){
        if (t!=null){
            System.out.println(t.element);
            printTreeNodeFirst(t.leftBinaryNode);
            printTreeNodeFirst(t.rightBinaryNode);
        }
    }

    public void printTreeNodeMedu(){ //中序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTreeNodeMedu(root);
        }
    }
    private void printTreeNodeMedu(BinaryNode<T> t){
        if (t!=null){
            printTreeNodeMedu(t.leftBinaryNode);
            System.out.print(t.element);
            printTreeNodeMedu(t.rightBinaryNode);
        }
    }

    public void printTree(){ //層序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTree(root);
        }
    }
    private void printTree(BinaryNode<T> t){
        ArrayQueue<BinaryNode<T>> arrayQueue=new ArrayQueue<>(height());
        if(t==null){
            System.out.println("Tree is empty");
        }
        arrayQueue.add(t);
        while (!arrayQueue.isEmpty()){
            BinaryNode<T> binaryNode=arrayQueue.remove(0);
            System.out.println(binaryNode.element);
            if(binaryNode.leftBinaryNode!=null){
                arrayQueue.add(binaryNode.leftBinaryNode);
            }
            if(binaryNode.rightBinaryNode!=null){
                arrayQueue.add(binaryNode.rightBinaryNode);
            }
        }
    }

    public void remove(T item){
        root=remove(item,root);
    }
    private BinaryNode<T> remove(T item,BinaryNode<T> t){
       if(t==null){
           return null;
       }
       int comparaValue=item.compareTo(t.element);
       if(comparaValue>0){
           t.rightBinaryNode=remove(item,t.rightBinaryNode);
       }
       else if(comparaValue<0) {
           t.leftBinaryNode=remove(item,t.leftBinaryNode);
       }
       else {
           if(t.rightBinaryNode!=null&&t.leftBinaryNode!=null){
               t.element=findMin(t.rightBinaryNode).element;
               t.rightBinaryNode=remove(t.element,t.rightBinaryNode);
           }
           else {
               t=(t.leftBinaryNode!=null)?t.leftBinaryNode:t.rightBinaryNode;
           }
       }
        return t;
    }

    private static class BinaryNode<T>{
        T element;
        BinaryNode<T> leftBinaryNode;
        BinaryNode<T> rightBinaryNode;

        BinaryNode(T element){
            this.element=element;
        }

        public BinaryNode(T element, BinaryNode<T> leftBinaryNode, BinaryNode<T> rightBinaryNode) {
            this.element = element;
            this.leftBinaryNode = leftBinaryNode;
            this.rightBinaryNode = rightBinaryNode;
        }

    }
}

3骏融、AVL樹
帶有自平衡調(diào)整的二叉查找樹链嘀,其要求每個節(jié)點的左右子節(jié)點的高度差萌狂,相差不超過1;


package tree;

import com.sun.org.apache.xerces.internal.impl.xpath.regex.Match;

import java.nio.BufferUnderflowException;

public class myAvlTree<T extends Comparable<? super T>> {
    private static final int ALLOWED_HEIGHT=1;
    private AvlNode<T> root;

    public myAvlTree(){
        root=null;
    }

    public boolean isEmpty(){
        return root==null;
    }
    public void insert(T item){
        root=insert(item,root);
    }


    public T findMin(){
        if(isEmpty())
            throw new BufferUnderflowException();
        return findMin(root).element;
    }
    private AvlNode<T> findMin(AvlNode<T> t){
        if(t==null){
            return null;
        }
        while (t.left!=null){
            t=t.left;
        }
        return t;
    }
    private AvlNode<T> insert(T item,AvlNode<T> t){
        if(t==null){
            return new AvlNode<T>(item,null,null);
        }
        int comparaValue=item.compareTo(t.element);
        if(comparaValue>0){
            t.right=insert(item,t.right);
        }
        else if(comparaValue<0){
            t.left=insert(item,t.left);
        }
        else
            ;
        return balance(t);
    }

    public void remove(T x){
        if(isEmpty()){
            System.out.println("tree is empty");
            throw new BufferUnderflowException();
        }
        remove(x,root);
    }
    private AvlNode<T> remove(T x,AvlNode<T> t){
        if(t==null){
            return null;
        }
        int comparaVaule=x.compareTo(t.element);
        if(comparaVaule>0){
            t.right=remove(x,t.right);
        }
        else if(comparaVaule<0){
            t.left=remove(x,t.left);
        }
        else if(t.left!=null&&t.right!=null){
            t.element=findMin(t.right).element;
            t.right=remove(t.element,t.left);
        }
        else {
            t=(t.left!=null)?t.left:t.right;
        }
        return t;
    }
    private AvlNode<T> balance(AvlNode<T> t){
        if(t==null){
            return t;
        }
        if(height(t.left)-height(t.right)>ALLOWED_HEIGHT){
            if(height(t.left.left)>=height(t.left.right)){
                t=rotateWithLeftChild(t);
            }
            else{
                t=doubleWithLeftChild(t);
            }
        }
        else if(height(t.right)-height(t.left)>ALLOWED_HEIGHT){
            if(height(t.right.right)>=height(t.right.left)){
                t=rotateWithRightChild(t);
            }
            else {
                t=doubleWithRightChild(t);
            }
        }
        t.height=Math.max(height(t.left),height(t.right))+1;
        return t;
    }
    private AvlNode<T> rotateWithLeftChild(AvlNode<T> k2){
        AvlNode<T> k1=k2.left;
        k2.left=k1.right;
        k1.right=k2;
        k2.height= Math.max(height(k2.left),height(k2.right))+1;
        k1.height=Math.max(height(k1.left),k2.height)+1;
        return k1;
    }
    private AvlNode<T> doubleWithLeftChild(AvlNode<T> k2){
        k2.left=rotateWithRightChild(k2.left);
        return rotateWithLeftChild(k2);
    }
    private AvlNode<T> rotateWithRightChild(AvlNode<T> k1){
        AvlNode<T> k2=k1.right;
        k1.right=k2.left;
        k2.left=k1;
        k1.height=Math.max(height(k1.right),k1.height);
        k2.height=Math.max(k1.height,height(k2.right))+1;
        return k2;
    }
    private AvlNode<T> doubleWithRightChild(AvlNode<T> k2){
        k2.right=rotateWithLeftChild(k2.left);
        return rotateWithRightChild(k2);
    }


    private int height(AvlNode<T> t){ //計算AVL樹的高度怀泊;
        return t==null?-1:t.height;
    }

    public void printTree(){ //后序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTree(root);
        }
    }
    private void printTree(AvlNode<T> t){
        if (t!=null){
            printTree(t.left);
            printTree(t.right);
            System.out.println(t.element);
        }
    }

    public void printTreelast(){ //先序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTreelast(root);
        }
    }
    private void printTreelast(AvlNode<T> t){
        if (t!=null){
            System.out.println(t.element);
            printTreelast(t.left);
            printTreelast(t.right);

        }
    }


    public void printTreemd(){ //中序遍歷
        if(isEmpty()){
            System.out.println("Tree is empty");
        }
        else {
            printTreemd(root);
        }
    }
    private void printTreemd(AvlNode<T> t){
        if (t!=null){
            printTreemd(t.left);
            System.out.println(t.element);
            printTreemd(t.right);

        }
    }

    private static class AvlNode<T>{
        T element;
        AvlNode<T> left;
        AvlNode<T> right;
        int height; //height
        AvlNode(T element){
            this.element=element;
        }
        public AvlNode(T element, AvlNode<T> left, AvlNode<T> right) {
            this.element = element;
            this.left = left;
            this.right = right;
            height=0;
        }

    }
}


 public static void main(String[] args){
        myAvlTree<Integer> myAvlTree=new myAvlTree<>();
        Integer[] integer={10,3,5,9,8,7,0,4};
        for(Integer ints:integer){
            myAvlTree.insert(ints);
        }
        System.out.println("中序");
        myAvlTree.printTreemd();
    }
    
    
中序
0
3
4
5
7
8
9
10

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茫藏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子霹琼,更是在濱河造成了極大的恐慌务傲,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枣申,死亡現(xiàn)場離奇詭異售葡,居然都是意外死亡,警方通過查閱死者的電腦和手機糯而,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門天通,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人熄驼,你說我怎么就攤上這事像寒。” “怎么了瓜贾?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵诺祸,是天一觀的道長。 經(jīng)常有香客問我祭芦,道長筷笨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任龟劲,我火速辦了婚禮胃夏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘昌跌。我一直安慰自己仰禀,他們只是感情好,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布蚕愤。 她就那樣靜靜地躺著答恶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萍诱。 梳的紋絲不亂的頭發(fā)上悬嗓,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音裕坊,去河邊找鬼包竹。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的映企。 我是一名探鬼主播悟狱,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼堰氓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起苹享,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤双絮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后得问,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囤攀,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年宫纬,在試婚紗的時候發(fā)現(xiàn)自己被綠了焚挠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡漓骚,死狀恐怖蝌衔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蝌蹂,我是刑警寧澤噩斟,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站孤个,受9級特大地震影響剃允,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜齐鲤,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一斥废、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧给郊,春花似錦牡肉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吩屹,卻和暖如春跪另,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背煤搜。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工免绿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人擦盾。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓嘲驾,卻偏偏與公主長得像淌哟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子辽故,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容