資料結構 老師:李崇明 助教:楊斯竣.

Slides:



Advertisements
Similar presentations
1 第八章 深入探討樹狀結構. 2 目次 8.1 m-way 搜尋樹 8.2 B-tree 8.3 動動腦時間 8.4 練習題解答.
Advertisements

第一單元 建立java 程式.
第7章 樹與二元樹 (Trees and Binary Trees)
Tree (2): heap, deap, 2-3 tree, 2-3-4tree
資料結構(計財系).
Chapter 6 樹狀結構.
Chapter 5 樹狀結構.
Chap4 Tree.
Tree(樹) 什麼是「樹」? 「樹」的範例 「樹」的定義 「樹」的表示法.
Chap5 Graph.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
資料結構 第3章 鏈結串列.
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置 4-2 鏈結串列的基礎 4-3 單向鏈結串列 4-4 環狀鏈結串列
資料結構設計與C++程式應用 Fundamentals of Data Structures and Their Applications Using C++ 第3章 佇列 資料結構設計與C++程式應用.
Chapter8 Binary and Other Trees
第11章 資料結構 – 使用C語言的模組 11-1 資料結構的基礎 11-2 C語言的模組化程式設計 11-3 基本鏈結串列
講師:郭育倫 第3章 基本資料結構 講師:郭育倫
第7章 樹與二元樹 (Trees and Binary Trees)
Course 0 課程介紹 Introduction
樹狀結構 Trees.
第12章 樹狀搜尋結構 (Search Trees)
資料結構與C++程式設計進階 鏈結串列 講師:林業峻 CSIE, NTU 6/ 10, 2010.
資料結構 第6章 樹狀結構.
SQL Stored Procedure SQL 預存程序.
(Circular Linked Lists)
第 七 章 樹狀結構 課程名稱:資料結構 授課老師:________ 2019/1/1.
資料結構–樹(Tree) 綠園.
4.1 單向鏈結串列 4.2 堆疊的加入與刪除 4.3 佇列的加入與刪除 4.4 其他型式的佇列
鄧姚文 資料結構 第六章:樹(Tree) 鄧姚文
Chapter 9 高度平衡二元搜尋樹 AVL Binary Search Tree
Java 程式設計 講師:FrankLin.
樹狀結構 Tree Structure chapter 7 德明科技大學資訊科技系.
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
JAVA 程式設計與資料結構 第四章 陣列、字串與數學物件.
Chap3 Linked List 鏈結串列.
Chapter 11 B-tree 11.1 m-way 搜尋樹 11.2 B-tree.
第六章 樹狀結構 T r e e 版權屬作者所有,非經作者 同意不得用於教學以外用途.
Ch 3 Dynamic Programming (動態規劃).
樹 2 Michael Tsai 2013/3/26.
第一單元 建立java 程式.
感謝同學們在加分題建議. 我會好好研讀+反省~
Chap4 Tree.
Tree & Binary Tree.
資料結構 7-1 陣列 7-2 鏈結串列 7-3 堆疊和佇列 7-4 樹狀結構.
資料結構使用Java 樹(Tree).
第 19 章 XML記憶體執行模式.
Reference to FUNDAMENTALS OF DATA STRUCTURE IN C++
第7章 樹與二元樹(Trees and Binary Trees)
圓的定義 在平面上,與一定點等距的所有點所形成的圖形稱為圓。定點稱為圓心,圓心至圓上任意一點的距離稱為半徑,「圓」指的是曲線部分的圖形,故圓心並不在圓上.
資料結構與C++程式設計進階 樹狀結構(Tree) 講師:林業峻 CSIE, NTU 11/ 12, 2009.
第 八 章 高等樹 課程名稱:資料結構 授課老師:________ 2019/4/28.
資料結構使用Java 第9章 樹(Tree).
資料結構 老師:李崇明 助教:楊斯竣.
C qsort.
講師:郭育倫 第3章 基本資料結構 講師:郭育倫
資料結構使用Java 第6章 鏈結串列(Linked List).
陣列與結構.
動畫演示 Node規範了一些基本的方法,像是增加節點、刪除節點、讓節點做一些事、取得第n個節點等等
6.1 樹狀結構的一些專有名詞 6.2 二元樹 6.3 二元樹的表示方法 6.4 二元樹的追蹤 6.5 引線二元樹 6.6 其它議題
第7章 資料結構 7-1 陣列 7-2 鏈結串列 7-3 堆疊和佇列 7-4 樹狀結構.
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
鏈結串列 Link List chapter 6 德明科技大學資訊科技系.
Trees 授課者:驕芸.
SQLite資料庫 靜宜大學資管系 楊子青.
10303: How Many Trees? ★★☆☆☆ 題組:Contest Archive with Online Judge
第10章 二元搜尋樹 (Binary Search Tree)
C語言程式設計 老師:謝孟諺 助教:楊斯竣.
JAVA 程式設計與資料結構 第十七章 Tree.
InputStreamReader Console Scanner
Presentation transcript:

資料結構 老師:李崇明 助教:楊斯竣

課程內容 6-1 樹的基本觀念 6-2 二元樹的基礎 6-3 二元樹的表示法 6-4 二元樹的走訪 6-5 二元搜尋樹 6-6 樹的二元樹表示法 6-7 二元樹的應用 - 運算式處理

6-1 樹的基本觀念-說明 「樹」(Trees)是一種模擬現實生活中樹幹和樹枝的資料結構,屬於一種階層架構的非線性資料結構,例如:家族族譜,如下圖所示:

6-1 樹的基本觀念-架構1 樹的樹根稱為「根節點」(Root),在根節點之下是樹的樹枝,擁有0到n個「子節點」(Children),即樹的「分支」(Branch),節點A是樹的根節點,B、C、D….和H是節點A的子節點,即樹枝,如下圖所示:

6-1 樹的基本觀念-架構2 在樹枝下還可以擁有下一層樹枝,I和J是B的子節點,K、L和M是E的子節點,節點B是I和J的「父節點」(Parent),節點E是K、L和M的父節點,節點I和J擁有共同父節點,稱為「兄弟節點」(Siblings),K、L和M 是兄弟節點,B、C…和H節點也是兄弟節點,如下圖所示:

6-1 樹的基本觀念-定義 定義 7.1:樹的節點個數是一或多個有限集合,且: (1) 存在一個節點稱為根節點。 (2) 在根節點下的節點分成n >= 0 個沒有交集的多個子集合t1、t2…, tn,每一個子集合也是一棵樹,而這些樹稱為根節點的「子樹」(Subtree)。 樹在各節點之間不可以有迴圈,或不連結的左、右子樹,如下圖所示:

6-1 樹的基本觀念-相關術語1 n元樹:樹的一個節點最多擁有n個子節點。 二元樹(Binary Trees):樹的節點最多只有兩個子節點。 根節點(Root):沒有父節點的節點是根節點。例如:節點A。 葉節點(Leaf):節點沒有子節點的節點稱為葉節點。例如:節點I、J、C、D、K、L、M、F、G和H。 祖先節點(Ancenstors):指某節點到根節點之間所經過的所有節點,都是此節點的祖先節點。

6-1 樹的基本觀念-相關術語2 非終端節點(Noterminal Nodes):除了葉節點之外的其它節點稱為非終端節點。例如:節點A、B和E是非終端節點。 分支度(Dregree):指每個節點擁有的子節點數。例如:節點B的分支度是2,節點E的分支度是3。 階層(Level):如果樹根是1,其子節點是2,依序可以計算出樹的階層數。例如:上述圖例的節點A階層是1,B、C到H是階層2,I、J到M是階層3。 樹高(Height):樹高又稱為樹深(Depth),指樹的最大階層數。例如:上述圖例的樹高是3。

6-2 二元樹的基礎-定義 樹依不同分支度可以區分成很多種,在資料結構中最廣泛使用的樹狀結構是「二元樹」(Binary Trees),二元樹是指樹中的每一個「節點」(Nodes)最多只能擁有2個子節點,即分支度小於或等於2。 二元樹的定義如下所示: 定義 7.2:二元樹的節點個數是一個有限集合,或是沒有節點的空集合。二元樹的節點可以分成兩個沒有交集的子樹,稱為「左子樹」(Left Subtree)和「右子樹」(Right Subtree)。

6-2 二元樹的基礎-圖例 二元樹 左子樹 右子樹

6-2 二元樹的基礎-歪斜樹 左邊這棵樹沒有右子樹,右邊這棵樹沒有左子樹,雖然擁有相同節點,但是這是兩棵不同的二元樹,因為所有節點都是向左子樹或右子樹歪斜,稱為「歪斜樹」(Skewed Tree),如下圖所示:

6-2 二元樹的基礎- 完滿二元樹(說明) 若二元樹的樹高是h且二元樹的節點數是2h-1,滿足此條件的樹稱為「完滿二元樹」(Full Binary Tree),如下圖所示:

6-2 二元樹的基礎- 完滿二元樹(節點數) 因為二元樹的每一個節點有2個子節點,二元樹樹高是3,也就是有3個階層(Level),各階層的節點數,如下所示: 第1階:1 = 2 (1-1) = 20 = 1 第2階:第1階節點數的2倍,1*2 = 2 (2-1) = 2 第3階:第2階節點數的2倍,2*2 = 2 (3-1) = 4 以此類推,可以得到每一階層的最大節點數是:2 (l-1),l是階層數,整棵二元樹的節點數一共是:20+21+22 = 7個,即23-1,可以得到: 20+21+22+….+2 (h-1) = 2h-1,h是樹高

6-2 二元樹的基礎-完整二元樹 若二元樹的節點不是葉節點,一定擁有兩個子節點,不過節點總數不足2h-1,其中h是樹高,滿足此條件的二元樹稱為「完整二元樹」(Complete Binary Tree),如下圖所示:

6-3 二元樹的表示法 6-3-1 二元樹陣列表示法 6-3-2 二元樹物件陣列表示法 6-3-3 二元樹鏈結表示法

6-3 二元樹的表示法 二元樹在實作上有多種方法可以建立二元樹,常用的方法有三種,如下所示: 二元樹陣列表示法。 二元樹物件陣列表示法。 二元樹鏈結表示法。

6-3-1 二元樹陣列表示法-說明1 完滿二元樹是一棵樹高h擁有2h-1個節點的二元樹,這是二元樹在樹高h所能擁有的最大節點數,換句話說,只需配置2h-1個元素,我們就可以儲存樹高h的二元樹,如下圖所示:

6-3-1 二元樹陣列表示法-說明2 二元樹的節點編號擁有循序性,根節點1的子節點是節點2和節點3,節點2是4和5,依此類推可以得到節點編號的規則,如下所示: 左子樹是父節點編號乘以2。 右子樹是父節點編號乘以2加1。

6-3-1 二元樹陣列表示法-二元樹類別 class BTree_Array { // 二元樹類別 private int[] btree; // 二元樹陣列宣告 // 建構子: 建立二元樹 public BTree_Array(int size, int[] array) { … … } // 方法: 顯示二元樹 public void printBTree() { …… } }

6-3-1 二元樹陣列表示法-成員方法

6-3-1 二元樹陣列表示法-建立二元樹(規則) BTree_Array()建構子以參數size的尺寸建立一維陣列儲存節點資料後,其建立規則,如下: 將第1個陣列元素插入成為二元樹的根節點。 將陣列元素值與二元樹的節點值比較,如果元素值大於節點值,將元素值插入成為節點的右子節點,如果右子節點不是空的,重覆比較節點值,直到找到插入位置後,將元素值插入二元樹。 如果元素值小於節點值,將元素值插入成為節點的左子節點,如果左子節點不是空的,繼續重覆比較,以便將元素值插入二元樹。

6-3-1 二元樹陣列表示法-建立二元樹(圖例) 二元樹陣列表示法圖例的索引值0並沒有使用,整個二元樹在16個陣列元素中使用的元素一共有9個,括號內是陣列的索引值,如下圖所示:

6-3-1 二元樹陣列表示法-顯示二元樹 printBTree()方法:顯示二元樹 printBTree()方法只是走訪btree[]陣列,將元素值不是-1的元素都顯示出來。

程式

6-3-1 二元樹陣列表示法-問題 一棵歪斜樹的二元樹陣列表示法使用不到三分之一的陣列元素4/16,因為二元樹的節點是以循序方式儲存在陣列中,如果需要插入或刪除節點,都需要在陣列中搬移大量元素,如下圖所示:

6-3-2二元樹物件陣列表示法-說明 在二元樹的每一個節點可以使用Java語言的節點物件來儲存,整棵二元樹是一個一維的物件陣列,data是節點資料,使用left和right成員變數的索引值指向子節點的索引值,如為-1表示沒有子節點,如下圖所示:

6-3-2二元樹物件陣列表示法-節點與二元樹類別 class Node { // 樹節點類別 int data; // 節點資料 int left; // 參考左子樹 int right; // 參考右子樹 } class BTree_Node { // 二元樹類別 private Node[] btree; // 二元樹陣列宣告 // 建構子: 建立二元樹 public BTree_Node(int size, int[] data) { …… } // 方法: 顯示二元樹 public void printBTree() { …… }

6-3-2二元樹物件陣列表示法-圖例 例如:一棵二元樹和其物件陣列表示法,如下圖所示:

6-3-3 二元樹鏈結表示法-說明 二元樹鏈結表示法是使用動態記憶體配置來建立二元樹,類似結構陣列表示法的節點結構,只是成員變數改成兩個指向左和右子樹的指標,如下圖所示:

6-3-3 二元樹鏈結表示法-TreeNode類別 鏈結串列實作的節點與二元樹類別:TreeNode和BTree class TreeNode { // 樹節點類別 int data; // 節點資料 TreeNode left; // 參考左子樹 TreeNode right; // 參考右子樹 // 建構子 public TreeNode(int data) { …… } }

6-3-3 二元樹鏈結表示法-BTree類別 public class BTree { // 二元樹類別 public TreeNode head; // 參考樹的根節點 // 建構子: 使用陣列建立二元樹 public BTree(int[] array) { …… } // 方法: 檢查二元樹是否是空的 boolean isBTreeEmpty() { …… } // 方法: 在二元樹插入節點 public void insertBTreeNode(int data) { …… } // 方法: 顯示二元樹的節點資料 public void printBTree() { …… } }

6-3-3 二元樹鏈結表示法-成員方法

6-3-3 二元樹鏈結表示法-建立二元樹(說明) BTree()建構子和insertBTreeNode()方法:建立二元樹 BTree()建構子只是使用for迴圈走訪參數的陣列元素,依序呼叫insertBTreeNode()方法將一個一個陣列元素的節點插入二元樹。 首先是二元樹的根節點5,left和right指標指向null,在建立二元樹的根節點5後,第二次呼叫insertBTreeNode()方法插入元素6,在比較二元樹根節點值5後,結果比較大,所以鏈結至右子樹。第三次呼叫插入元素4,經比較插入成為根節點的左子樹。等到執行完建構子的for迴圈後,建立的二元樹。

6-3-3 二元樹鏈結表示法-建立二元樹(圖例)

6-3-3 二元樹鏈結表示法-顯示二元樹 printBTree()方法:顯示二元樹 printBTree()方法使用while迴圈分別走訪二元樹的左右分支,不過這個方法並沒有辦法顯示二元樹的全部節點資料。

程式

6-4 二元樹的走訪 6-4-1 中序走訪方式 6-4-2 前序走訪方式 6-4-3 後序走訪方式

6-4 二元樹的走訪-說明 陣列和單向鏈結串列都只能從頭至尾或從尾至頭執行單向「走訪」(Traverse),不過二元樹的每一個節點都擁有指向左和右2個子節點的指標,所以走訪可以有兩條路徑。例如:一棵二元樹,如下圖所示:

6-4 二元樹的走訪-種類 二元樹的走訪過程是持續決定向左或向右走,直到沒路可走。很明顯的!二元樹的走訪是一種遞迴走訪,依照遞迴方法中呼叫的排列順序不同,可以分成三種走訪方式,如下所示: 中序走訪方式(Inorder Traversal)。 前序走訪方式(Preorder Traversal)。 後序走訪方式(Postorder Traversal)。

6-4-1 中序走訪方式-說明 中序走訪是沿著二元樹的左方往下走,直到無法繼續前進後,顯示節點,退回到父節點顯示父節點,然後繼續往右走,如果右方都無法前進,顯示節點,再退回到上一層。依照中序走訪第6-4節的二元樹,其顯示的節點順序,如下所示: 1,2,3,4,5,6,7,8,9 在上述中序走訪節點順序中,可以看出根節點5是位在正中間,之前都是左子樹的節點,之後都是右子樹的節點。

6-4-1 中序走訪方式-演算法 中序走訪的遞迴方法inOrder()使用二元樹指標ptr進行走訪,中序走訪的步驟,如下所示: Step 1:檢查是否可以繼續前進,即指標ptr不等於null。 Step 2:如果可以前進,其處理方式如下所示: (1) 遞迴呼叫inOrder(ptr.left)向左走。 (2) 處理目前的節點,顯示節點資料。 (3) 遞迴呼叫inOrder(ptr.right)向右走。

程式

6-4-1 中序走訪方式-遞迴呼叫

6-4-2 前序走訪方式-說明 前序走訪方式是走訪到的二元樹節點,就立刻顯示節點資料,走訪的順序是先向樹的左方走直到無法前進後,才轉往右方走。依照前序走訪第6-4節的二元樹,其顯示的節點順序,如下所示: 5,4,2,1,3,6,8,7,9 在上述前序走訪節點順序中,可以看出根節點5一定是第1個,左右子樹的根節點一定在其它節點之前。

6-4-2 前序走訪方式-演算法 前序走訪的遞迴方法preOrder()使用二元樹指標ptr進行走訪,前序走訪的步驟,如下所示: Step 1:先檢查是否已經到達葉節點,也就是指標ptr等於null。 Step 2:如果不是葉節點表示可以繼續走,其處理方式如下所示: (1) 處理目前的節點,顯示節點資料。 (2) 遞迴呼叫preOrder(ptr.left)向左走。 (3) 遞迴呼叫preOrder(ptr.right)向右走。

6-4-2 前序走訪方式-遞迴呼叫

程式

6-4-3 後序走訪方式-說明 後序走訪方式剛好和前序走訪相反,它是等到節點的2個子節點都走訪過後才執行處理,顯示節點資料。依照後序走訪第6-4節的二元樹,其顯示的節點順序,如下所示: 1,3,2,4,7,9,8,6,5 在上述後序走訪節點順序中,可以看出根節點5是最後1個,而且左右子樹的根節點一定在其它節點之後。

6-4-3 後序走訪方式-演算法 後序走訪的遞迴方法postOrder()使用二元樹指標ptr進行走訪,後序走訪的步驟,如下所示: Step 1:先檢查是否已經到達葉節點,就是指標ptr等於null。 Step 2:如果不是葉節點表示可以繼續走,其處理方式如下所示: (1) 遞迴呼叫postOrder(ptr.left)向左走。 (2) 遞迴呼叫postOrder(ptr.right)向右走。 (3) 處理目前的節點,顯示節點資料。

6-4-3 後序走訪方式-遞迴呼叫

程式

Binary Search Tree 二元搜尋樹

二元搜尋樹(Binary Search Tree) 為一種「有大小順序」的二元樹。 任何節點 左子樹之值小於節點的值 右子樹之值大於節點的值 左子樹和右子樹亦是二元搜尋樹。 將二元搜尋樹中序追蹤,即可得到排序後由小至大的資料。 50 30 72 42 95

建立二元搜尋樹 建立二元搜尋樹時,必須加入大小排序規則: 以第一個資料當作樹根 之後之資料與樹根比較 若小於樹根則成為樹根之左子樹 若大於樹根則成為樹根之右子樹 如此一直遞迴之進行。

建立二元搜尋樹 輸入資料: 37, 57, 23, 15, 32。

建立二元搜尋樹-程式碼 使用者輸入的第一個數字成為樹根節點(root)。 建立insert方法來新增節點。 treeNode root = new treeNode(sc.nextInt()); 建立insert方法來新增節點。 呼叫insert時傳入新節點(newNode)參數。 root.insert(new treeNode(sc.nextInt())); insert方法判斷目前節點與新節點的data大小 新節點data較小:新增到左子樹。 新節點data較大:新增到右子樹。 若左、右子樹為空,則直接將新節點掛上。

建立二元搜尋樹-程式碼 if(newNode.data < data){ //新節點data較小 if(left == null) //左子樹為空 left = newNode; else left.insert(newNode); //新增到左子樹 }else{ if(right == null) right = newNode; right.insert(newNode); }

刪除二元搜尋樹節點 若是樹葉節點:直接刪除 若是內部節點: 例:刪除右圖50 在左子樹找數值最大的節點取代之 或是在右子樹找數值最小的節點取代之 例:刪除右圖50 50 40 65 45 30 60

刪除二元搜尋樹節點 60 40 65 45 30 取右子樹最小的節點 或是取左子樹最大的節點 45 40 65 60 30