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     }

posted @ 2017-06-19 15:30  JiYF  阅读(10463)  评论(1编辑  收藏  举报