.
二元搜尋樹(Binary Search Tree)指一棵空樹或者具有下列性質的二元樹:
1. 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值
2.若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值
3.任意節點的左、右子樹也分別為二元搜尋樹
4.沒有鍵值相等的節點
二元搜尋樹的功能不外乎基本的新增、搜尋、刪除
不過此篇主要介紹的為 二元搜尋樹的尋訪( Binary Search Tree traversal)
尋訪方式主要分為三種,前序(preorder) 中序(inprder) 後序(postorder)
前序(Pre-order)
訪問根節點
訪問左子樹
訪問右子樹
中序(In-order)
訪問左子樹
訪問根節點
訪問右子樹
後序(Post-order)
訪問左子樹
訪問右子樹
訪問根節點
可用下圖來概括說明
而此篇用到的搜尋為 Depth-first search(DFS) 深度優先搜索
是一種用來遍尋一個樹(tree)或圖(graph)的演算法
由樹的根(或圖的某一點當成 根)來開始探尋
先探尋邊(edge)上未搜尋的一節點(vertex or node),並儘可能深的搜索
直到該節點的所有邊上節點都已探尋
就回溯(backtracking)到前一個節點,重覆探尋未搜尋的節點
直到找到目的節點或遍尋全部節點
最後為實作程式碼
使用下圖的樹來進行尋訪
Main:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
-
- namespace TreeSearch
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
-
- private void Form1_Load(object sender, EventArgs e)
- {
- Tree BST = new Tree();
- BST.Insert(50);
- BST.Insert(17);
- BST.Insert(23);
- BST.Insert(12);
- BST.Insert(19);
- BST.Insert(54);
- BST.Insert(9);
- BST.Insert(14);
- BST.Insert(67);
- BST.Insert(76);
- BST.Insert(72);
- //Console.WriteLine("Inorder Traversal : ");
- textBox1.Text = BST.Inorder(BST.ReturnRoot());
- //Console.WriteLine("Preorder Traversal : ");
- textBox2.Text = BST.Preorder(BST.ReturnRoot());
- //Console.WriteLine("Postorder Traversal : ");
- textBox3.Text = BST.Postorder(BST.ReturnRoot());
- }
- }
- }
Class Node
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- namespace TreeSearch
- {
- class Node
- {
- public int item;
- public Node left;
- public Node right;
- }
- }
Class Tree
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- namespace TreeSearch
- {
- class Tree
- {
- private String preorder_path = "", inorder_path = "", postorder_path = "";
- public Node root;
- public Tree()
- {
- root = null;
- }
- public Node ReturnRoot()
- {
- return root;
- }
- public void Insert(int id)
- {
- Node newNode = new Node();
- newNode.item = id;
- if (root == null) //如果跟是空,則新加入的點為根
- root = newNode;
- else
- {
- Node current = root; //如果根不為空,則當前的點設成根
- Node parent; //宣告父節點
- while (true)
- {
- parent = current; //設定父節點為根
- if (id < current.item) //如果當前值小於父節點
- {
- current = current.left; //把當前節點歸為左子樹
- if (current == null) //如果左子樹為空
- {
- parent.left = newNode; //新增一個節點
- return;
- }
- }
- else
- {
- current = current.right; //如果當前值大於父節點,將其歸右子樹
- if (current == null) //如果右子樹為空
- {
- parent.right = newNode; // 新增一個節點
- return;
- }
- }
- }
- }
- }
- public String Preorder(Node Root)
- {
-
- if (Root != null)
- {
- preorder_path += Root.item + " ";
- Preorder(Root.left);
- Preorder(Root.right);
-
- }
- return preorder_path;
- }
- public String Inorder(Node Root)
- {
- if (Root != null)
- {
- Inorder(Root.left);
- inorder_path += Root.item + " ";
- Inorder(Root.right);
- }
- return inorder_path;
- }
- public String Postorder(Node Root)
- {
- if (Root != null)
- {
- Postorder(Root.left);
- Postorder(Root.right);
- postorder_path += Root.item + " ";
- }
- return postorder_path;
- }
- }
- }
執行結果