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

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

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

服務(wù)器之家 - 編程語言 - Java教程 - Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

2022-02-28 00:48pier~呀 Java教程

樹是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹中稱為結(jié)點(diǎn))按分支關(guān)系組織起來的結(jié)構(gòu),很象自然界中的樹那樣。樹結(jié)構(gòu)在客觀世界中廣泛存在,如人類社會的族譜和各種社會組織機(jī)構(gòu)都可用樹形象表示

前言

本章,我們主要需要了解以下內(nèi)容

  • 什么是線索二叉樹
  • 怎么去把二叉樹線索化
  • 怎么通過線索二叉樹查找某個(gè)數(shù)的后繼結(jié)點(diǎn)
  • 二叉樹的查看——二叉樹怎們遍歷

 什么是線索二叉樹

首先我們來了解一下什么是線索二叉樹?

定義:一個(gè)二叉樹通過如下的方法“穿起來”:所有原本為空的右(孩子)指針改為指向該節(jié)點(diǎn)在中序序列中的后繼,所有原本為空的左(孩子)指針改為指向該節(jié)點(diǎn)的中序序列的前驅(qū)。

再看一下為什么要有線索二叉樹?

顧名思義,線索二叉樹,肯定是根據(jù)線索查找,查找速度肯定更快。

  • 線索二叉樹能線性地遍歷二叉樹,從而比遞歸的中序遍歷更快。使用線索二叉樹也能夠方便的找到一個(gè)節(jié)點(diǎn)的父節(jié)點(diǎn),這比顯式地使用父親節(jié)點(diǎn)指針或者棧效率更高。這在棧空間有限,或者無法使用存儲父節(jié)點(diǎn)的棧時(shí)很有作用(對于通過深度優(yōu)先搜索來查找父節(jié)點(diǎn)而言)。

那線索僅僅是這樣嗎?當(dāng)然不,我們都是懶的,能等待解決的問題,為什么會去想新的辦法。我們要解決的是:

  • 為了解決無法直接找到該結(jié)點(diǎn)在某種遍歷序列中的前驅(qū)和后繼結(jié)點(diǎn)的問題
  • 但是同時(shí)出現(xiàn)了二叉鏈表找左、右孩子困難的問題,即在構(gòu)建線索二叉樹之后,鏈表的原來遍歷方式會出問題。

最后看一下什么線索二叉樹的圖解

在我們的線索二叉樹的書上,基本上都有以下這張圖:

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

大家看到上面這張圖還是有點(diǎn)懵的叭,我們一起看一下我下面手畫的圖

怎么去把二叉樹線索化

哦!在著之前獻(xiàn)給大家提一下,二叉樹的遍歷方式,有這樣的幾種

  • 前序遍歷二叉樹的遞歸定義(根左右)
  • 中序遍歷二叉樹的遞歸定義(左根右)
  • 后續(xù)遍歷二叉樹的遞歸意義(左右根)

本博文主要討論的是中序遍歷
它的中序遍歷結(jié)果就是abcde f ghi

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

它的中序線索二叉樹遍歷如下

先畫線索二叉樹

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

虛線箭頭為線索指針,對于所有左指針指向空的節(jié)點(diǎn):將該節(jié)點(diǎn)的左指針指向該節(jié)點(diǎn)在中序遍歷中的上一節(jié)點(diǎn);對于所有右指針指向空的節(jié)點(diǎn),將該節(jié)點(diǎn)的右指針指向該節(jié)點(diǎn)在中序遍歷中的下一結(jié)點(diǎn)。最后一個(gè)末尾結(jié)點(diǎn)除外。
中序圖解線索二叉樹

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

怎么通過線索二叉樹查找某個(gè)數(shù)的后繼結(jié)點(diǎn)

即形成了一個(gè)特殊的雙向鏈表,之所以特殊,以f–>e為例,f–>e并不是直接到達(dá),而是通過f–>b–>d–>e間接到達(dá)。

我們嘗試用java去構(gòu)建一顆線索二叉樹叭

先申明,我從未使用java構(gòu)建過樹,二叉樹都沒有,若有錯(cuò)誤,請指出

數(shù)據(jù)結(jié)點(diǎn)類

?
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
package com.testtree;
 
/**
 * @author pier
 */
public class treenode {
    /**數(shù)據(jù)域**/
    private int data;
    /**左指針**/
    private treenode left;
    /** 左孩子是否為線索,采用布爾類型主要是判斷是否未null足以**/
    private boolean leftisthread;
    /**右指針**/
    private treenode right;
    /** 右孩子是否為線索**/
    private boolean rightisthread;
 
    /**根據(jù)數(shù)據(jù)域來確定所在的指針對應(yīng)位置**/
    public treenode(int data)
    {
        this.data = data;
        this.left = null;
        this.leftisthread = false;
        this.right = null;
        this.rightisthread = false;
    }
 
    public int getdata()
    {
        return data;
    }
 
    public void setdata(int data)
    {
        this.data = data;
    }
 
    public treenode getleft()
    {
        return left;
    }
 
    public void setleft(treenode left)
    {
        this.left = left;
    }
 
    public boolean isleftisthread()
    {
        return leftisthread;
    }
 
    public void setleftisthread(boolean leftisthread)
    {
        this.leftisthread = leftisthread;
    }
 
    public treenode getright()
    {
        return right;
    }
 
    public void setright(treenode right)
    {
        this.right = right;
    }
 
    public boolean isrightisthread()
    {
        return rightisthread;
    }
 
    public void setrightisthread(boolean rightisthread)
    {
        this.rightisthread = rightisthread;
    }
 
    @override
    public boolean equals(object obj)
    {
        if (obj instanceof treenode )
        {
            treenode temp = (treenode) obj;
            if (temp.getdata() == this.data)
            {
                return true;
            }
        }
        return false;
    }
 
    @override
    public int hashcode()
    {
        return super.hashcode() + this.data;
    }
}

二叉樹類

?
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
package com.testtree;
/*author:pier
2021/10/12
*/
 
public class bitree {
    /** 根節(jié)點(diǎn) **/
    private treenode root;
    /** 大小 **/
    private int size;
    /** 線索化的時(shí)候保存前驅(qū) **/
    private treenode pre = null;
 
    public bitree()
    {
        this.root = null;
        this.size = 0;
        this.pre = null;
    }
 
    public bitree(int[] data)
    {
        this.pre = null;
        this.size = data.length;
        // 創(chuàng)建二叉樹
        this.root = createtree(data, 1);
    }
 
    /**
     * 創(chuàng)建二叉樹
     *
     */
    public treenode createtree(int[] data, int index)
    {
        if (index > data.length)
        {
            return null;
        }
        treenode node = new treenode(data[index - 1]);
        treenode left = createtree(data, 2 * index);
        treenode right = createtree(data, 2 * index + 1);
        node.setleft(left);
        node.setright(right);
        return node;
    }
    /**中序遍歷**/
    public void inlist(treenode root)
    {
        if (root != null)
        {
            inlist(root.getleft());
            system.out.print(root.getdata() + ",");
            inlist(root.getright());
        }
    }
 
    public treenode getroot()
    {
        return root;
    }
 
    public void setroot(treenode root)
    {
        this.root = root;
    }
 
    public int getsize()
    {
        return size;
    }
 
    public void setsize(int size)
    {
        this.size = size;
    }
    /**線索化二叉樹**/
    public void inthread(treenode root) {
        if ( root != null ) {
            // 線索化左孩子
            inthread(root.getleft());
            // 左孩子為空
            if ( null == root.getleft() )
            {
                // 將左孩子設(shè)置為線索
                root.setleftisthread(true);
                root.setleft(pre);
            }
            // 右孩子為空
            if ( pre != null && null == pre.getright() )
            {
                pre.setrightisthread(true);
                pre.setright(root);
            }
            pre = root;
            // 線索化右孩子
            inthread(root.getright());
        }
    }
    /**
     * 中序遍歷線索二叉樹
     *
     */
    public void inthreadlist(treenode root)
    {
        if (root != null)
        {
            // 如果左孩子不是線索
            while (root != null && !root.isleftisthread())
            {
                root = root.getleft();
            }
 
            do
            {
                // 如果右孩子是線索
                system.out.print(root.getdata() + ",");
                if (root.isrightisthread())
                {
                    root = root.getright();
                }
                // 有右孩子
                else
                {
                    root = root.getright();
                    while (root != null && !root.isleftisthread())
                    {
                        root = root.getleft();
                    }
                }
            } while (root != null);
        }
    }
}

測試類

?
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
package com.testtree;
 
/**
 * @author pier
 */
public class test {
    public static void main(string[] args) {
    //不要問我為什么設(shè)置這么大,結(jié)尾看我效果截圖
        int[] arr = new int[10000];
        for (int i = 0; i < arr.length; i++) {
            arr[i]=i+1;
        }
        //創(chuàng)建一顆二叉樹
        bitree bitree = new bitree(arr);
        //中序遍歷二叉樹
        system.out.println("中序遍歷結(jié)果如下:");
        long start1 = system.currenttimemillis();
        bitree.inlist(bitree.getroot());
        long end1 = system.currenttimemillis();
        system.out.println();
        system.out.println("普通遍歷時(shí)間為:"+(end1-start1)+"毫秒");
        system.out.println("\n");
        //中序遍歷將二叉樹線索化
        bitree.inthread(bitree.getroot());
        system.out.println("線索二叉樹中序遍歷如下:");
        long start2 = system.currenttimemillis();
        bitree.inthreadlist(bitree.getroot());
        long end2 = system.currenttimemillis();
        system.out.println();
        system.out.println("線索二叉樹的遍歷時(shí)間為:"+(end2-start2)+"毫秒");
 
    }
}

運(yùn)行結(jié)果

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析


當(dāng)我使用1-10的時(shí)候效果截圖

Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析

完全看不出來差距,所以,哈哈才設(shè)置那么大,能夠?qū)嵺`出來線索二叉樹的遍歷速度確實(shí)更快的。

ps:看完這篇文章,你不來點(diǎn)個(gè)贊嗎?不來個(gè)三連嗎?重點(diǎn)是,你今天get到了嗎?別之后alt+insert自動生成get喲,用你那看起來不聰明的小腦袋瓜想一想。

到此這篇關(guān)于java數(shù)據(jù)結(jié)構(gòu)二叉樹難點(diǎn)解析的文章就介紹到這了,更多相關(guān)java 二叉樹內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/qq_43325476/article/details/120716127

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男女性gif抽搐出入视频 | 精品国产欧美一区二区三区成人 | 999任你躁在线精品免费不卡 | 60老妇性xxxxhd| 99精品在线视频 | 国产成人无精品久久久久国语 | 韩国www| kuaibo成人播放器 | 2021国产精品视频一区 | 手机看片国产免费现在观看 | 成人在线免费看 | 黄动漫车车好快的车车双女主 | 美女被吸乳老师羞羞漫画 | 久久这里只精品热在线18 | 国产欧美一区二区三区免费 | 吃大胸寡妇的奶 | 久久草福利自拍视频在线观看 | 国产在线精品一区二区高清不卡 | 欧美夫妇野外交换hd高清版 | 我年轻漂亮的继坶2中字在线播放 | 国产在线视频欧美亚综合 | 手机看片国产免费现在观看 | 男女做性视频 | 国产日韩一区二区三区 | 欧美亚洲一区二区三区 | 97色轮| 四虎永久在线精品波多野结衣 | 国模大胆一区二区三区 | 999久久久| 国产66| 欧美a在线 | 天天操天天射天天色 | 午夜第一页 | 国产亚洲精品一区在线播 | 久久黄色精品视频 | 美女的隐私视频免费看软件 | 免费观看俄罗斯特黄特色 | 五月婷婷在线免费观看 | 四虎精品在线观看 | 男男互操文 | 穆挂英风流艳史小说 |