C#實現二叉樹--二叉鏈表結構


二叉樹的簡單介紹

關於二叉樹的介紹請看這里 :

二叉樹的簡單介紹 http://www.cnblogs.com/JiYF/p/7048785.html


 

二叉鏈表存儲結構:

二叉樹的鏈式存儲結構是指,用鏈表來表示一棵二叉樹,即用鏈來指示元素的邏輯關系。

通常的方法是鏈表中每個結點由三個域組成,數據域和左右指針域,左右指針分別用來給出該結點左孩子和右孩子所在的鏈結點的存儲地址。其結點結構為:

  其中,data域存放某結點的數據信息;lchild與rchild分別存放指向左孩子和右孩子的指針,當左孩子或右孩子不存在時,相應指針域值為空(用符號∧或NULL表示)。利用這樣的結點結構表示的二叉樹的鏈式存儲結構被稱為二叉鏈表,如圖5-8所示。  

C#實現代碼

二叉樹的節點類:

 1 Binary Tree
 2 
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 
 8 namespace DataStructure
 9 {
10     /// <summary>
11     /// 二叉鏈表結點類
12     /// </summary>
13     /// <typeparam name="T"></typeparam>
14     public  class TreeNode<T>
15     {
16         private T data;               //數據域
17         private TreeNode<T> lChild;   //左孩子   樹中一個結點的子樹的根結點稱為這個結點的孩子
18         private TreeNode<T> rChild;   //右孩子
19 
20         public TreeNode(T val, TreeNode<T> lp, TreeNode<T> rp)
21         {
22             data = val;
23             lChild = lp;
24             rChild = rp;
25         }
26 
27         public TreeNode(TreeNode<T> lp, TreeNode<T> rp)
28         {
29             data = default(T);
30             lChild = lp;
31             rChild = rp;
32         }
33 
34         public TreeNode(T val)
35         {
36             data = val;
37             lChild = null;
38             rChild = null;
39         }
40 
41         public TreeNode()
42         {
43             data = default(T);
44             lChild = null;
45             rChild = null;
46         }
47 
48         public T Data
49         {
50             get { return data; }
51             set { data = value; }
52         }
53 
54         public TreeNode<T> LChild
55         {
56             get { return lChild; }
57             set { lChild = value; }
58         }
59 
60         public TreeNode<T> RChild
61         {
62             get { return rChild; }
63             set { rChild = value; }
64         }
65 
66     }
定義索引文件結點的數據類型
  1  /// <summary>
  2     /// 定義索引文件結點的數據類型
  3     /// </summary>
  4     public struct indexnode
  5     {
  6         int key;         //
  7         int offset;      //位置
  8         public indexnode(int key, int offset)
  9         {
 10             this.key = key;
 11             this.offset = offset;
 12         }
 13 
 14         //鍵屬性
 15         public int Key
 16         {
 17             get { return key; }
 18             set { key = value; }
 19         }
 20         //位置屬性
 21         public int Offset
 22         {
 23             get { return offset; }
 24             set { offset = value; }
 25         }
 26 
 27 
 28     }
 29 
 30 
 31     public class LinkBinaryTree<T>
 32     {
 33         private TreeNode<T> head;       //頭引用
 34 
 35         public TreeNode<T> Head
 36         {
 37             get { return head; }
 38             set { head = value; }
 39         }
 40 
 41         public LinkBinaryTree()
 42         {
 43             head = null;
 44         }
 45 
 46         public LinkBinaryTree(T val)
 47         {
 48             TreeNode<T> p = new TreeNode<T>(val);
 49             head = p;
 50         }
 51 
 52         public LinkBinaryTree(T val, TreeNode<T> lp, TreeNode<T> rp)
 53         {
 54             TreeNode<T> p = new TreeNode<T>(val, lp, rp);
 55             head = p;
 56         }
 57 
 58         //判斷是否是空二叉樹
 59         public bool IsEmpty()
 60         {
 61             if (head == null)
 62                 return true;
 63             else
 64                 return false;
 65         }
 66 
 67         //獲取根結點
 68         public TreeNode<T> Root()
 69         {
 70             return head;
 71         }
 72 
 73         //獲取結點的左孩子結點
 74         public TreeNode<T> GetLChild(TreeNode<T> p)
 75         {
 76             return p.LChild;
 77         }
 78 
 79         public TreeNode<T> GetRChild(TreeNode<T> p)
 80         {
 81             return p.RChild;
 82         }
 83 
 84         //將結點p的左子樹插入值為val的新結點,原來的左子樹稱為新結點的左子樹
 85         public void InsertL(T val, TreeNode<T> p)
 86         {
 87             TreeNode<T> tmp = new TreeNode<T>(val);
 88             tmp.LChild = p.LChild;
 89             p.LChild = tmp;
 90         }
 91 
 92         //將結點p的右子樹插入值為val的新結點,原來的右子樹稱為新節點的右子樹
 93         public void InsertR(T val, TreeNode<T> p)
 94         {
 95             TreeNode<T> tmp = new TreeNode<T>(val);
 96             tmp.RChild = p.RChild;
 97             p.RChild = tmp;
 98         }
 99 
100         //若p非空 刪除p的左子樹
101         public TreeNode<T> DeleteL(TreeNode<T> p)
102         {
103             if ((p == null) || (p.LChild == null))
104                 return null;
105             TreeNode<T> tmp = p.LChild;
106             p.LChild = null;
107             return tmp;
108         }
109 
110         //若p非空 刪除p的右子樹
111         public TreeNode<T> DeleteR(TreeNode<T> p)
112         {
113             if ((p == null) || (p.RChild == null))
114                 return null;
115             TreeNode<T> tmp = p.RChild;
116             p.RChild = null;
117             return tmp;
118         }
119 
120         //編寫算法 在二叉樹中查找值為value的結點
121 
122         public TreeNode<T> Search(TreeNode<T> root, T value)
123         {
124             TreeNode<T> p = root;
125             if (p == null)
126                 return null;
127             if (!p.Data.Equals(value))
128                 return p;
129             if (p.LChild != null)
130             {
131                 return Search(p.LChild, value);
132             }
133             if (p.RChild != null)
134             {
135                 return Search(p.RChild, value);
136             }
137             return null;
138         }
139 
140         //判斷是否是葉子結點
141         public bool IsLeaf(TreeNode<T> p)
142         {
143             if ((p != null) && (p.RChild == null) && (p.LChild == null))
144                 return true;
145             else
146                 return false;
147         }
148 
149 
150         //中序遍歷
151         //遍歷根結點的左子樹->根結點->遍歷根結點的右子樹 
152         public void inorder(TreeNode<T> ptr)
153         {
154             if (IsEmpty())
155             {
156                 Console.WriteLine("Tree is Empty !");
157                 return;
158             }
159             if (ptr != null)
160             {
161                 inorder(ptr.LChild);
162                 Console.WriteLine(ptr.Data + " ");
163                 inorder(ptr.RChild);
164             }
165         }
166 
167 
168         //先序遍歷
169         //根結點->遍歷根結點的左子樹->遍歷根結點的右子樹 
170         public void preorder(TreeNode<T> ptr)
171         {
172             if (IsEmpty())
173             {
174                 Console.WriteLine("Tree is Empty !");
175                 return;
176             }
177             if (ptr != null)
178             {
179                 Console.WriteLine(ptr.Data + " ");
180                 preorder(ptr.LChild);
181                 preorder(ptr.RChild);
182             }
183         }
184 
185 
186         //后序遍歷
187         //遍歷根結點的左子樹->遍歷根結點的右子樹->根結點
188         public void postorder(TreeNode<T> ptr)
189         {
190             if (IsEmpty())
191             {
192                 Console.WriteLine("Tree is Empty !");
193                 return;
194             }
195             if (ptr != null)
196             {
197                 postorder(ptr.LChild);
198                 postorder(ptr.RChild);
199                 Console.WriteLine(ptr.Data + "");
200             }
201         }
202 
203 
204         //層次遍歷
205         //引入隊列 
206         public void LevelOrder(TreeNode<T> root)
207         {
208             if (root == null)
209             {
210                 return;
211             }
212             CSeqQueue<TreeNode<T>> sq = new CSeqQueue<TreeNode<T>>(50);
213             sq.EnQueue(root);
214             while (!sq.IsEmpty())
215             {
216                 //結點出隊
217                 TreeNode<T> tmp = sq.DeQueue();
218                 //處理當前結點
219                 Console.WriteLine("{0}", tmp);
220                 //將當前結點的左孩子結點入隊
221                 if (tmp.LChild != null)
222                 {
223                     sq.EnQueue(tmp.LChild);
224                 }
225                 if (tmp.RChild != null)
226                 {
227                     sq.EnQueue(tmp.RChild);
228                 }
229             }
230         }
231     }
二叉搜索樹:結點的左子節點的值永遠小於該結點的值,而右子結點的值永遠大於該結點的值 稱為二叉搜索樹
  1 /// <summary>
  2     /// 二叉搜索樹:結點的左子節點的值永遠小於該結點的值,而右子結點的值永遠大於該結點的值 稱為二叉搜索樹
  3     /// </summary>
  4     public class LinkBinarySearchTree : LinkBinaryTree<indexnode>
  5     {
  6         //定義增加結點的方法
  7         public void insert(indexnode element)
  8         {
  9             TreeNode<indexnode> tmp, parent = null, currentNode = null;
 10             //調用FIND方法
 11             find(element, ref parent, ref currentNode);
 12             if (currentNode != null)
 13             {
 14                 Console.WriteLine("Duplicates words not allowed");
 15                 return;
 16             }
 17             else
 18             {
 19                 //創建結點
 20                 tmp = new TreeNode<indexnode>(element);
 21                 if (parent == null)
 22                     Head = tmp;
 23                 else
 24                 {
 25                     if (element.Key < parent.Data.Key)
 26                         parent.LChild = tmp;
 27                     else
 28                         parent.RChild = tmp;
 29                 }
 30             }
 31         }
 32 
 33         //定義父結點
 34         public void find(indexnode element, ref TreeNode<indexnode> parent, ref TreeNode<indexnode> currentNode)
 35         {
 36             currentNode = Head;
 37             parent = null;
 38             while ((currentNode != null) && (currentNode.Data.Key.ToString() != element.Key.ToString()) && (currentNode.Data.Offset .ToString() != element.Offset .ToString()))//
 39             {
 40                 parent = currentNode;
 41                 if (element.Key < currentNode.Data.Key)
 42                     currentNode = currentNode.LChild;
 43                 else
 44                     currentNode = currentNode.RChild;
 45             }
 46         }
 47 
 48         //定位結點
 49         public void find(int key)
 50         {
 51             TreeNode<indexnode> currentNode = Head;
 52             while ((currentNode != null) && (currentNode.Data.Key.ToString () != key.ToString ()))
 53             {
 54                 Console.WriteLine(currentNode.Data.Offset.ToString());
 55                 if (key < currentNode.Data.Key)
 56                     currentNode = currentNode.LChild;
 57                 else
 58                     currentNode = currentNode.RChild;
 59             }
 60         }
 61 
 62         //中序遍歷
 63         //遍歷根結點的左子樹->根結點->遍歷根結點的右子樹 
 64         public void inorderS(TreeNode<indexnode> ptr)
 65         {
 66             if (IsEmpty())
 67             {
 68                 Console.WriteLine("Tree is Empty !");
 69                 return;
 70             }
 71             if (ptr != null)
 72             {
 73                 inorderS(ptr.LChild);
 74                 Console.WriteLine(ptr.Data.Key  + " ");
 75                 inorderS(ptr.RChild);
 76             }
 77         }
 78 
 79 
 80         //先序遍歷
 81         //根結點->遍歷根結點的左子樹->遍歷根結點的右子樹 
 82         public void preorderS(TreeNode<indexnode> ptr)
 83         {
 84             if (IsEmpty())
 85             {
 86                 Console.WriteLine("Tree is Empty !");
 87                 return;
 88             }
 89             if (ptr != null)
 90             {
 91                 Console.WriteLine(ptr.Data.Key  + " ");
 92                 preorderS(ptr.LChild);
 93                 preorderS(ptr.RChild);
 94             }
 95         }
 96 
 97 
 98         //后序遍歷
 99         //遍歷根結點的左子樹->遍歷根結點的右子樹->根結點
100         public void postorderS(TreeNode<indexnode> ptr)
101         {
102             if (IsEmpty())
103             {
104                 Console.WriteLine("Tree is Empty !");
105                 return;
106             }
107             if (ptr != null)
108             {
109                 postorderS(ptr.LChild);
110                 postorderS(ptr.RChild);
111                 Console.WriteLine(ptr.Data.Key + "");
112             }
113         }
114     }
115 
116 
117     /// <summary>
118     /// 循環順序隊列
119     /// </summary>
120     /// <typeparam name="T"></typeparam>
121     class CSeqQueue<T>
122     {
123         private int maxsize;       //循環順序隊列的容量
124         private T[] data;          //數組,用於存儲循環順序隊列中的數據元素
125         private int front;         //指示最近一個已經離開隊列的元素所占有的位置 循環順序隊列的對頭
126         private int rear;          //指示最近一個進入隊列的元素的位置           循環順序隊列的隊尾
127 
128         public T this[int index]
129         {
130             get { return data[index]; }
131             set { data[index] = value; }
132         }
133 
134         //容量屬性
135         public int Maxsize
136         {
137             get { return maxsize; }
138             set { maxsize = value; }
139         }
140 
141         //對頭指示器屬性
142         public int Front
143         {
144             get { return front; }
145             set { front = value; }
146         }
147 
148         //隊尾指示器屬性
149         public int Rear
150         {
151             get { return rear; }
152             set { rear = value; }
153         }
154 
155         public CSeqQueue()
156         {
157 
158         }
159 
160         public CSeqQueue(int size)
161         {
162             data = new T[size];
163             maxsize = size;
164             front = rear = -1;
165         }
166 
167         //判斷循環順序隊列是否為滿
168         public bool IsFull()
169         {
170             if ((front == -1 && rear == maxsize - 1) || (rear + 1) % maxsize == front)
171                 return true;
172             else
173                 return false;
174         }
175 
176         //清空循環順序列表
177         public void Clear()
178         {
179             front = rear = -1;
180         }
181 
182         //判斷循環順序隊列是否為空
183         public bool IsEmpty()
184         {
185             if (front == rear)
186                 return true;
187             else
188                 return false;
189         }
190 
191         //入隊操作
192         public void EnQueue(T elem)
193         {
194             if (IsFull())
195             {
196                 Console.WriteLine("Queue is Full !");
197                 return;
198             }
199             rear = (rear + 1) % maxsize;
200             data[rear] = elem;
201         }
202 
203         //出隊操作
204         public T DeQueue()
205         {
206             if (IsEmpty())
207             {
208                 Console.WriteLine("Queue is Empty !");
209                 return default(T);
210             }
211             front = (front + 1) % maxsize;
212             return data[front];
213         }
214 
215         //獲取對頭數據元素
216         public T GetFront()
217         {
218             if (IsEmpty())
219             {
220                 Console.WriteLine("Queue is Empty !");
221                 return default(T);
222             }
223             return data[(front + 1) % maxsize];//front從-1開始
224         }
225 
226         //求循環順序隊列的長度
227         public int GetLength()
228         {
229             return (rear - front + maxsize) % maxsize;
230         }
231     }
 
          


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM