【資料結構】手撕二叉查詢樹(Binary Search Tree)
阿新 • • 發佈:2021-01-22
文章目錄
備註:實現語言為C#(.NET Core),語法和Java別無二致
第一步 構建結點類
class Node
{
public int data { get; set; }
public Node Left { get; set ; }
public Node Right { get; set; }
public Node() { }
public Node(int val)
{
data = val;
Left = null;
Right = null;
}
}
第二步 實現結點新增方法
public int Add(int val)
{
if (root == null)
root = new Node(val);
else
{
Node node = root;
while (node != null)
{
if (val < node.data)
{
if(node.Left != null)
{
node = node.Left;
continue;
}
node.Left = new Node(val);
break;
}
else if (val == node.data) return -1; //重複則不新增,直接返回-1
else
{
if (node.Right != null)
{
node = node.Right;
continue;
}
node.Right = new Node(val);
break;
}
}
}
Size++;
return 0;
}
第三步 實現結點的刪除方法(重難點)
//外部API
public void Del(int val)
{
root = Del(root, val);
}
//遞迴實現部分
private Node Del(Node node, int val)
{
if (node == null)
return null;
if(val < node.data)
{
node.Left = Del(node.Left, val);
return node;
}
else if(val > node.data)
{
node.Right = Del(node.Right, val);
return node;
}
else //找到要刪除的結點
{
if(node.Left == null)
{
if(node.Right == null) //沒有孩子結點
{
node = null;
return node;
}
else //有右孩子
{
node = node.Right;
return node;
}
}
else
{
if(node.Right == null) //有左孩子
{
node = node.Left;
return node;
}
else //左右孩子都有
{
//找到右子樹中最小的結點替換要刪除的結點
Node findMin = node.Right;
while (findMin.Left != null)
findMin = findMin.Left;
node.data = findMin.data;
node.Right = Del(node.Right, findMin.data);
return node;
}
}
}
}
第四步 實現結點的查詢方法
public bool Have(int val)
{
Node node = root;
while(node != null)
{
if (val < node.data)
node = node.Left;
else if (val > node.data)
node = node.Right;
else
return true;
}
return false;
}
第五步 實現二叉樹的先序遍歷演算法
//外部API
public void Previous_travel()
{
Previous_travel(root);
}
//遞迴實現部分
private void Previous_travel(Node node)
{
if (node != null)
{
Console.Write(node.data + " ");
Previous_travel(node.Left);
Previous_travel(node.Right);
}
}
第六步 實現二叉樹的中序遍歷演算法
//外部API
public void Medium_travel()
{
Medium_travel(root);
}
//遞迴實現部分
private void Medium_travel(Node node)
{
if (node != null)
{
Medium_travel(node.Left);
Console.Write(node.data + " ");
Medium_travel(node.Right);
}
}
第七步 實現二叉樹的後序遍歷演算法
//外部API
public void Post_travel()
{
Post_travel(root);
}
//遞迴實現部分
private void Post_travel(Node node)
{
if (node != null)
{
Post_travel(node.Left);
Post_travel(node.Right);
Console.Write(node.data + " ");
}
}
第八步 實現二叉樹的層次遍歷演算法(難點)
public void layer_travel()
{
Queue<Node> nodes = new Queue<Node>();//需要藉助佇列暫存每層的孩子結點
nodes.Enqueue(root);
Node node = null;
while(nodes.Count != 0)
{
node = nodes.Dequeue();
if(node != null)
{
Console.Write(node.data + " ");
if (node.Left != null)
nodes.Enqueue(node.Left);
if (node.Right != null)
nodes.Enqueue(node.Right);
}
}
}
完整程式碼實現
using System;
using System.Collections.Generic;
namespace DataStructure
{
// 結點類
class Node
{
public int data { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
public Node() { }
public Node(int val)
{
data = val;
Left = null;
Right = null;
}
}
// 二叉搜尋樹
class BinarySearchTree
{
private Node root;
public int Size { get; set; }
public BinarySearchTree()
{
root = null;
Size = 0;
}
//結點新增
public int Add(int val)
{
if (root == null)
root = new Node(val);
else
{
Node node = root;
while (node != null)
{
if (val < node.data)
{
if(node.Left != null)
{
node = node.Left;
continue;
}
node.Left = new Node(val);
break;
}
else if (val == node.data) return -1;
else
{
if (node.Right != null)
{
node = node.Right;
continue;
}
node.Right = new Node(val);
break;
}
}
}
Size++;
return 0;
}
//結點刪除
public void Del(int val)
{
root = Del(root, val);
}
private Node Del(Node node, int val)
{
if (node == null)
return null;
if(val < node.data)
{
node.Left = Del(node.Left, val);
return node;
}
else if(val > node.data)
{
node.Right = Del(node.Right, val);
return node;
}
else //找到要刪除的結點
{
if(node.Left == null)
{
if(node.Right == null) //沒有孩子結點
{
node = null;
return node;
}
else //有右孩子
{
node = node.Right;
return node;
}
}
else
{
if(node.Right == null) //有左孩子
{
node = node.Left;
return node;
}
else //左右孩子都有
{
//找到右子樹中最小的結點替換要刪除的結點
Node findMin = node.Right;
while (findMin.Left != null)
findMin = findMin.Left;
node.data = findMin.data;
node.Right = Del(node.Right, findMin.data);
return node;
}
}
}
}
//查詢結點
public bool Have(int val)
{
Node node = root;
while(node != null)
{
if (val < node.data)
node = node.Left;
else if (val > node.data)
node = node.Right;
else
return true;
}
return false;
}
//先序遍歷
public void Previous_travel()
{
Previous_travel(root);
}
private void Previous_travel(Node node)
{
if (node != null)
{
Console.Write(node.data + " ");
Previous_travel(node.Left);
Previous_travel(node.Right);
}
}
//中序遍歷
public void Medium_travel()
{
Medium_travel(root);
}
private void Medium_travel(Node node)
{
if(node != null)
{
Medium_travel(node.Left);
Console.Write(node.data + " ");
Medium_travel(node.Right);
}
}
//後序遍歷
public void Post_travel()
{
Post_travel(root);
}
private void Post_travel(Node node)
{
if(node != null)
{
Post_travel(node.Left);
Post_travel(node.Right);
Console.Write(node.data + " ");
}
}
//層次遍歷
public void layer_travel()
{
Queue<Node> nodes = new Queue<Node>();
nodes.Enqueue(root);
Node node = null;
while(nodes.Count != 0)
{
node = nodes.Dequeue();
if(node != null)
{
Console.Write(node.data + " ");
if (node.Left != null)
nodes.Enqueue(node.Left);
if (node.Right != null)
nodes.Enqueue(node.Right);
}
}
}
}
}
除錯程式碼及執行結果
using System;
namespace DataStructure
{
class Program
{
static void Main(string[] args)
{
string[] nums = Console.ReadLine().Split(" ");
BinarySearchTree tree = new BinarySearchTree();
foreach (string num in nums)
tree.Add(int.Parse(num));
Console.WriteLine("樹中元素的個數為:{0}", tree.Size);
if (tree.Have(2))
Console.WriteLine("樹中包含2這個元素");
else
Console.WriteLine("樹中不包含2這個元素");
Console.Write("先序遍歷結果:");
tree.Previous_travel();
Console.Write("\n中序遍歷結果:");
tree.Medium_travel();
Console.Write("\n後序遍歷結果:");
tree.Post_travel();
Console.Write("\n層序遍歷結果:");
tree.layer_travel();
Console.Write("\n請輸入要刪除的元素:");
int del = int.Parse(Console.ReadLine());
tree.Del(del);
Console.Write("刪除後先序遍歷結果:");
tree.Previous_travel();
Console.Write("\n刪除後中序遍歷結果:");
tree.Medium_travel();
Console.Write("\n刪除後後序遍歷結果:");
tree.Post_travel();
Console.Write("\n刪除後層序遍歷結果:");
tree.layer_travel();
Console.ReadKey();
}
}
}
執行結果: