-TREE-

by h94usu/6

CONTENTS

  • Introduction 介紹
    • definitions 定義
    • terms 術語
    • properties 性質
  • Set up a tree 建立
  • Binary tree 二元樹
  • Traversal 遍歷
 

Introduction

"樹"的基本介紹

definition 定義

  • 任兩點之間都相通,沒環的連通圖
    • ​「環」: 能繞圈
    • 「連通」: 任兩點皆有路線使相連

環     

連通

v

v

x

x

v

v

x

v

v

x

x

x

terms 術語

a

b

c

d

e

f

g

根節點 root

節點 node

葉節點 leaf node

邊 edge

terms 術語

a

b

c

d

e

f

g

d, c 為b 的子節點 child

b, c 為兄弟節點 siblings

a 為 b, c 的父節點 parent

a, b 為d 的祖先 ancestor

d, e, g 為b 的子代 descendant

為b 的子樹 subtree

分4 層level,  深度depth 為4

level 0

level 1

level 2

level 3

properties 性質

  • 任何節點皆可當根節點
  • 任兩點恰有一條無重複點的路徑
  • 一棵n 個節點的樹恰有(n-1) 條邊

a

b

c

d

e

b

d

a

e

c

5 個節點

4 條邊

Set Up a Tree

建立一棵"樹"

linked list   (不好的方法)

0
 Advanced issue found
 
  • 建一個名Node 的structure
    • ​存節點的值
    • 存Node型態指標
#inlcude <iostream>
using namespace std;

struct Node{
    int _data; //不一定是int
    Node *_child1, *_child2, *_child3... ;
};

△注意: 不確定有幾個子節點,開太大會造成記憶體的浪費

linked list   (好方法)

  • 建一個名Node 的structure
    • ​存節點的值
    • 用vector 紀錄其子節點
#inlcude <iostream>
#include <vector>
using namespace std;

struct Node{
    int _data; //不一定是int
    vector<Node*> _child;
};

dynamic array   (最常用)

  • 建兩個陣列
    • ​建一個陣列存每個節點的數值
    • 開一個vector 陣列存每個編號的子節點
#inlcude <iostream>
#include <vector>
using namespace std;

int data[size];
vector<int> child[size];
//size 即為節點個數

Binary Tree

二元樹

definition 定義

  • 一個沒環的連通圖
  • 每個節點定義有唯一的父節點且不大於2個子節點
#inlcude <iostream>
using namespace std;

struct Node{
    int _data; 
    Node *left_child, *right_child;
};

properties 性質

  • 第i 層最最多有2^i 個節點
  • 深度為k 的二元樹最多有2^(k+1)-1 個節點
  • 葉節點數 = 分支度為2 的節點數 + 1
  • 二元樹的節點有左、右次序之分
  • 第n 個節點
    • ​child 為編號2n, 2n+1
    • patent 為 n/ 2

△注意: 定義根節點所在深度為第0 層

a

b

c

d

e

f

Types 二元樹的種類

0
 Advanced issue found
 
  • 滿二元樹 full binary tree
  • 完全二元樹 complete binary tree
  • perfect binary tree

a

b

c

d

e

f

a

b

c

d

e

f

d

full binary tree

complete binary tree

Full Binary Tree 滿二元樹

0
 Advanced issue found
 
  • 每一層上的節點數都是最大節點數(2個)
  • 一棵深度為k 的滿二元樹
    • 第i 層有2^i 個節點
    • 有2^k - 1個節點
    • 有2^(k-1) 個葉節點
  • 節點各樹必為奇數

a

b

c

d

e

f

d

full binary tree

Complete Binary Tree 完全二元樹

0
 Advanced issue found
 
  • 除最後一層每層節點數都是最大節點數(2個)
  • 最後一層不是滿的就是右邊缺一節點
  • 深度為k 的完全二元樹
  • 有2^(k-1) 個葉節點
    • ​至少有2^(k-1) 個節點
    • 至多有2^k - 1個節點

a

b

c

d

e

f

complete binary tree

Tree Traversal

"樹"的遍歷

Types 遍歷的種類

0
 Advanced issue found
 
  • 深度優先遍歷 Depth-first search (DFS)
    • 前序遍歷 Pre-Order
    • 中序遍歷 In-Order
    • 後序遍歷 Post-Order
  • 廣度優先遍歷 Breadth-first search (BFS)
    • 層序遍歷 Level-order

Pre-Order 前序遍歷

0
 Advanced issue found
 
  • 先存取根,再存取子樹
void pre_order_traversal(Node *root) {
    cout << root->data << " ";
    if (root->left_child != NULL) //如有子代則讀取其子樹
        pre_order_traversal(root->left_child);
    if (root->right_child != NULL) //另一側
        pre_order_traversal(root->right_child); 
}

a

b

c

d

e

output:  a b d e c

△根在最前

In-Order 中序遍歷

0
 Advanced issue found
 
  • 先存取左子樹,再存取根,最後存取右子樹
void in_order_traversal(Node *root) {
    if (root->left_child != NULL) //如有子代則讀取其子樹
        in_order_traversal(root->left_child);
    cout << root->data << " ";
    if (root->right_child != NULL) //另一側
        in_order_traversal(root->right_child); 
}

a

b

c

d

e

output:  d b e a c

△根在中間

Post-Order 後序遍歷

0
 Advanced issue found
 
  • 先存取子樹,再存取根
void post_order_traversal(Node *root) {
    if (root->left_child != NULL) //如有子代則讀取其子樹
        post_order_traversal(root->left_child);
    if (root->right_child != NULL) //另一側
        post_order_traversal(root->right_child); 
    cout << root->data << " ";
}

a

b

c

d

e

output:  d e b c a

△根在最後

Level-Order 層序遍歷

0
 Advanced issue found
 
  • 先存取離根節點最近的節點
void level_order_traversal(node *root) {
    int head = 0, tail = 0;
    node *p[SIZE] = {NULL};
    node *tmp;
    if (root != NULL) {
        p[head] = root;
        tail++;
        cout << p[head]->data << " ";
    } 
    else return;
    while (head < tail) {
        tmp = p[head];
        cout << root->data << " "; 
        if (tmp->left_child != NULL) { //如有子代則讀取其子樹
            p[tail] = tmp->left_child;
            tail++;
        }
        if (tmp->right_child != NULL) { //另一側
            p[tail] = tmp->right_child;
            tail++;
        }
        head++;
    }
    return;
}

a

b

c

d

e

output:  a b c d e

0
 Advanced issue found
 

△根在最前

Tree

By h94usu6

Tree

自助學習成發

  • 132