使用C#操作二叉樹的插入查詢遍歷和列印(程式碼)
阿新 • • 發佈:2018-12-19
Node類:
public class Node { public int Item { set; get; } //節點資料 public Node LeftChild { set; get; } //左子節點的引用 public Node RightChild { set; get; } //右子節點的引用 public bool IsDelete { set; get; }//表示節點是否被刪除 public Node(int data) { this.Item = data; } }
二叉樹的插入、刪除、列印、查詢最大值、最小值、中序遍歷、前序遍歷、後序遍歷
public class BinaryTree { //表示根節點 public Node _root; public void PrintTree(Node head, int height, string to, int len) { if (head == null) { return; } PrintTree(head.RightChild, height + 1, "right", len); string val = to + "\""+head.Item +"\""+ to; int lenM = val.Length; int lenL = (len - lenM) / 2; int lenR = len - lenM - lenL; val = GetSpace(lenL) + val + GetSpace(lenR); Console.WriteLine(GetSpace(height * len) + val); PrintTree(head.LeftChild, height + 1, "left", len); } public string GetSpace(int num) { string space = " "; StringBuilder buf = new StringBuilder(""); for (int i = 0; i < num; i++) { buf.Append(space); } return buf.ToString(); } //查詢節點 public Node Find(int key) { Node current = _root; while (current != null) { if (current.Item > key) {//當前值比查詢值大,搜尋左子樹 current = current.LeftChild; } else if (current.Item < key) {//當前值比查詢值小,搜尋右子樹 current = current.RightChild; } else { return current; } } return null;//遍歷完整個樹沒找到,返回null } //插入節點 public bool Insert(int data) { Node newNode = new Node(data); if (_root == null) {//當前樹為空樹,沒有任何節點 _root = newNode; return true; } else { Node current = _root; Node parentNode = null; while (current != null) { parentNode = current; if (current.Item > data) {//當前值比插入值大,搜尋左子節點 current = current.LeftChild; if (current == null) {//左子節點為空,直接將新值插入到該節點 parentNode.LeftChild = newNode; return true; } } else { current = current.RightChild; if (current == null) {//右子節點為空,直接將新值插入到該節點 parentNode.RightChild = newNode; return true; } } } } return false; } //中序遍歷 public void InfixOrder(Node current) { if (current != null) { InfixOrder(current.LeftChild); Console.WriteLine(current.Item + " "); InfixOrder(current.RightChild); } } //前序遍歷 public void PreOrder(Node current) { if (current != null) { Console.WriteLine(current.Item + " "); InfixOrder(current.LeftChild); InfixOrder(current.RightChild); } } //後序遍歷 public void PostOrder(Node current) { if (current != null) { InfixOrder(current.LeftChild); InfixOrder(current.RightChild); Console.WriteLine(current.Item + " "); } } //找到最大值 public Node FindMax() { Node current = _root; Node maxNode = current; while (current != null) { maxNode = current; current = current.RightChild; } return maxNode; } //找到最小值 public Node FindMin() { Node current = _root; Node minNode = current; while (current != null) { minNode = current; current = current.LeftChild; } return minNode; } public bool RemoveTree(int key) { Node current = _root; Node parent = _root; bool isLeftChild = false; //查詢刪除值,找不到直接返回false while (current.Item != key) { parent = current; if (current.Item > key) { isLeftChild = true; current = current.LeftChild; } else { isLeftChild = false; current = current.RightChild; } if (current == null) { return false; } } //如果當前節點沒有子節點 if (current.LeftChild == null && current.RightChild == null) { if (current == _root) { _root = null; } else if (isLeftChild) { parent.LeftChild = null; } else { parent.RightChild = null; } return true; //當前節點有一個子節點,右子節點 } else if (current.LeftChild == null && current.RightChild != null) { if (current == _root) { _root = current.RightChild; } else if (isLeftChild) { parent.LeftChild = current.RightChild; } else { parent.RightChild = current.RightChild; } return true; //當前節點有一個子節點,左子節點 } else if (current.LeftChild != null && current.RightChild == null) { if (current == _root) { _root = current.LeftChild; } else if (isLeftChild) { parent.LeftChild = current.LeftChild; } else { parent.RightChild = current.LeftChild; } return true; } else { //當前節點存在兩個子節點 Node successor = GetSuccessor(current); if (current == _root) { successor = _root; } else if (isLeftChild) { parent.LeftChild = successor; } else { parent.RightChild = successor; } successor.LeftChild = current.LeftChild; } return false; } private Node GetSuccessor(Node delNode) { Node successorParent = delNode; Node successor = delNode; Node current = delNode.RightChild; while (current != null) { successorParent = successor; successor = current; current = current.LeftChild; } //後繼節點不是刪除節點的右子節點,將後繼節點替換刪除節點 if (successor != delNode.RightChild) { successorParent.LeftChild = successor.RightChild; successor.RightChild = delNode.RightChild; } return successor; } }
測試程式碼:
static void Main(string[] args) { BinaryTree bt = new BinaryTree(); bt.Insert(50); bt.Insert(20); bt.Insert(80); bt.Insert(10); bt.Insert(30); bt.Insert(60); bt.Insert(90); bt.Insert(25); bt.Insert(85); bt.Insert(100); bt.PrintTree(bt._root,0,"root",10); bt.RemoveTree(10);//刪除沒有子節點的節點 bt.RemoveTree(30);//刪除有一個子節點的節點 bt.RemoveTree(80);//刪除有兩個子節點的節點 Console.WriteLine("--------------------------------------------------------------"); bt.PrintTree(bt._root, 0, "root", 10); Console.WriteLine(bt.FindMax().Item); Console.WriteLine(bt.FindMin().Item); Console.WriteLine(bt.Find(100)); Console.WriteLine(bt.Find(200)); Console.ReadKey(); }