C#实现二叉树 二叉链表结构

二叉链表存储结构:

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。

通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。其结点结构为:

其中,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     }
 67
 68     /// <summary>
 69     /// 定义索引文件结点的数据类型
 70     /// </summary>
 71     public struct indexnode
 72     {
 73         int key;         //键
 74         int offset;      //位置
 75         public indexnode(int key, int offset)
 76         {
 77             this.key = key;
 78             this.offset = offset;
 79         }
 80
 81         //键属性
 82         public int Key
 83         {
 84             get { return key; }
 85             set { key = value; }
 86         }
 87         //位置属性
 88         public int Offset
 89         {
 90             get { return offset; }
 91             set { offset = value; }
 92         }
 93
 94
 95     }
 96
 97
 98     public class LinkBinaryTree<T>
 99     {
100         private TreeNode<T> head;       //头引用
101
102         public TreeNode<T> Head
103         {
104             get { return head; }
105             set { head = value; }
106         }
107
108         public LinkBinaryTree()
109         {
110             head = null;
111         }
112
113         public LinkBinaryTree(T val)
114         {
115             TreeNode<T> p = new TreeNode<T>(val);
116             head = p;
117         }
118
119         public LinkBinaryTree(T val, TreeNode<T> lp, TreeNode<T> rp)
120         {
121             TreeNode<T> p = new TreeNode<T>(val, lp, rp);
122             head = p;
123         }
124
125         //判断是否是空二叉树
126         public bool IsEmpty()
127         {
128             if (head == null)
129                 return true;
130             else
131                 return false;
132         }
133
134         //获取根结点
135         public TreeNode<T> Root()
136         {
137             return head;
138         }
139
140         //获取结点的左孩子结点
141         public TreeNode<T> GetLChild(TreeNode<T> p)
142         {
143             return p.LChild;
144         }
145
146         public TreeNode<T> GetRChild(TreeNode<T> p)
147         {
148             return p.RChild;
149         }
150
151         //将结点p的左子树插入值为val的新结点,原来的左子树称为新结点的左子树
152         public void InsertL(T val, TreeNode<T> p)
153         {
154             TreeNode<T> tmp = new TreeNode<T>(val);
155             tmp.LChild = p.LChild;
156             p.LChild = tmp;
157         }
158
159         //将结点p的右子树插入值为val的新结点,原来的右子树称为新节点的右子树
160         public void InsertR(T val, TreeNode<T> p)
161         {
162             TreeNode<T> tmp = new TreeNode<T>(val);
163             tmp.RChild = p.RChild;
164             p.RChild = tmp;
165         }
166
167         //若p非空 删除p的左子树
168         public TreeNode<T> DeleteL(TreeNode<T> p)
169         {
170             if ((p == null) || (p.LChild == null))
171                 return null;
172             TreeNode<T> tmp = p.LChild;
173             p.LChild = null;
174             return tmp;
175         }
176
177         //若p非空 删除p的右子树
178         public TreeNode<T> DeleteR(TreeNode<T> p)
179         {
180             if ((p == null) || (p.RChild == null))
181                 return null;
182             TreeNode<T> tmp = p.RChild;
183             p.RChild = null;
184             return tmp;
185         }
186
187         //编写算法 在二叉树中查找值为value的结点
188
189         public TreeNode<T> Search(TreeNode<T> root, T value)
190         {
191             TreeNode<T> p = root;
192             if (p == null)
193                 return null;
194             if (!p.Data.Equals(value))
195                 return p;
196             if (p.LChild != null)
197             {
198                 return Search(p.LChild, value);
199             }
200             if (p.RChild != null)
201             {
202                 return Search(p.RChild, value);
203             }
204             return null;
205         }
206
207         //判断是否是叶子结点
208         public bool IsLeaf(TreeNode<T> p)
209         {
210             if ((p != null) && (p.RChild == null) && (p.LChild == null))
211                 return true;
212             else
213                 return false;
214         }
215
216
217         //中序遍历
218         //遍历根结点的左子树->根结点->遍历根结点的右子树
219         public void inorder(TreeNode<T> ptr)
220         {
221             if (IsEmpty())
222             {
223                 Console.WriteLine("Tree is Empty !");
224                 return;
225             }
226             if (ptr != null)
227             {
228                 inorder(ptr.LChild);
229                 Console.WriteLine(ptr.Data + " ");
230                 inorder(ptr.RChild);
231             }
232         }
233
234
235         //先序遍历
236         //根结点->遍历根结点的左子树->遍历根结点的右子树
237         public void preorder(TreeNode<T> ptr)
238         {
239             if (IsEmpty())
240             {
241                 Console.WriteLine("Tree is Empty !");
242                 return;
243             }
244             if (ptr != null)
245             {
246                 Console.WriteLine(ptr.Data + " ");
247                 preorder(ptr.LChild);
248                 preorder(ptr.RChild);
249             }
250         }
251
252
253         //后序遍历
254         //遍历根结点的左子树->遍历根结点的右子树->根结点
255         public void postorder(TreeNode<T> ptr)
256         {
257             if (IsEmpty())
258             {
259                 Console.WriteLine("Tree is Empty !");
260                 return;
261             }
262             if (ptr != null)
263             {
264                 postorder(ptr.LChild);
265                 postorder(ptr.RChild);
266                 Console.WriteLine(ptr.Data + "");
267             }
268         }
269
270
271         //层次遍历
272         //引入队列
273         public void LevelOrder(TreeNode<T> root)
274         {
275             if (root == null)
276             {
277                 return;
278             }
279             CSeqQueue<TreeNode<T>> sq = new CSeqQueue<TreeNode<T>>(50);
280             sq.EnQueue(root);
281             while (!sq.IsEmpty())
282             {
283                 //结点出队
284                 TreeNode<T> tmp = sq.DeQueue();
285                 //处理当前结点
286                 Console.WriteLine("{0}", tmp);
287                 //将当前结点的左孩子结点入队
288                 if (tmp.LChild != null)
289                 {
290                     sq.EnQueue(tmp.LChild);
291                 }
292                 if (tmp.RChild != null)
293                 {
294                     sq.EnQueue(tmp.RChild);
295                 }
296             }
297         }
298     }
299
300     /// <summary>
301     /// 二叉搜索树:结点的左子节点的值永远小于该结点的值,而右子结点的值永远大于该结点的值 称为二叉搜索树
302     /// </summary>
303     public class LinkBinarySearchTree : LinkBinaryTree<indexnode>
304     {
305         //定义增加结点的方法
306         public void insert(indexnode element)
307         {
308             TreeNode<indexnode> tmp, parent = null, currentNode = null;
309             //调用FIND方法
310             find(element, ref parent, ref currentNode);
311             if (currentNode != null)
312             {
313                 Console.WriteLine("Duplicates words not allowed");
314                 return;
315             }
316             else
317             {
318                 //创建结点
319                 tmp = new TreeNode<indexnode>(element);
320                 if (parent == null)
321                     Head = tmp;
322                 else
323                 {
324                     if (element.Key < parent.Data.Key)
325                         parent.LChild = tmp;
326                     else
327                         parent.RChild = tmp;
328                 }
329             }
330         }
331
332         //定义父结点
333         public void find(indexnode element, ref TreeNode<indexnode> parent, ref TreeNode<indexnode> currentNode)
334         {
335             currentNode = Head;
336             parent = null;
337             while ((currentNode != null) && (currentNode.Data.Key.ToString() != element.Key.ToString()) && (currentNode.Data.Offset .ToString() != element.Offset .ToString()))//
338             {
339                 parent = currentNode;
340                 if (element.Key < currentNode.Data.Key)
341                     currentNode = currentNode.LChild;
342                 else
343                     currentNode = currentNode.RChild;
344             }
345         }
346
347         //定位结点
348         public void find(int key)
349         {
350             TreeNode<indexnode> currentNode = Head;
351             while ((currentNode != null) && (currentNode.Data.Key.ToString () != key.ToString ()))
352             {
353                 Console.WriteLine(currentNode.Data.Offset.ToString());
354                 if (key < currentNode.Data.Key)
355                     currentNode = currentNode.LChild;
356                 else
357                     currentNode = currentNode.RChild;
358             }
359         }
360
361         //中序遍历
362         //遍历根结点的左子树->根结点->遍历根结点的右子树
363         public void inorderS(TreeNode<indexnode> ptr)
364         {
365             if (IsEmpty())
366             {
367                 Console.WriteLine("Tree is Empty !");
368                 return;
369             }
370             if (ptr != null)
371             {
372                 inorderS(ptr.LChild);
373                 Console.WriteLine(ptr.Data.Key  + " ");
374                 inorderS(ptr.RChild);
375             }
376         }
377
378
379         //先序遍历
380         //根结点->遍历根结点的左子树->遍历根结点的右子树
381         public void preorderS(TreeNode<indexnode> ptr)
382         {
383             if (IsEmpty())
384             {
385                 Console.WriteLine("Tree is Empty !");
386                 return;
387             }
388             if (ptr != null)
389             {
390                 Console.WriteLine(ptr.Data.Key  + " ");
391                 preorderS(ptr.LChild);
392                 preorderS(ptr.RChild);
393             }
394         }
395
396
397         //后序遍历
398         //遍历根结点的左子树->遍历根结点的右子树->根结点
399         public void postorderS(TreeNode<indexnode> ptr)
400         {
401             if (IsEmpty())
402             {
403                 Console.WriteLine("Tree is Empty !");
404                 return;
405             }
406             if (ptr != null)
407             {
408                 postorderS(ptr.LChild);
409                 postorderS(ptr.RChild);
410                 Console.WriteLine(ptr.Data.Key + "");
411             }
412         }
413     }
414
415
416     /// <summary>
417     /// 循环顺序队列
418     /// </summary>
419     /// <typeparam name="T"></typeparam>
420     class CSeqQueue<T>
421     {
422         private int maxsize;       //循环顺序队列的容量
423         private T[] data;          //数组,用于存储循环顺序队列中的数据元素
424         private int front;         //指示最近一个已经离开队列的元素所占有的位置 循环顺序队列的对头
425         private int rear;          //指示最近一个进入队列的元素的位置           循环顺序队列的队尾
426
427         public T this[int index]
428         {
429             get { return data[index]; }
430             set { data[index] = value; }
431         }
432
433         //容量属性
434         public int Maxsize
435         {
436             get { return maxsize; }
437             set { maxsize = value; }
438         }
439
440         //对头指示器属性
441         public int Front
442         {
443             get { return front; }
444             set { front = value; }
445         }
446
447         //队尾指示器属性
448         public int Rear
449         {
450             get { return rear; }
451             set { rear = value; }
452         }
453
454         public CSeqQueue()
455         {
456
457         }
458
459         public CSeqQueue(int size)
460         {
461             data = new T[size];
462             maxsize = size;
463             front = rear = -1;
464         }
465
466         //判断循环顺序队列是否为满
467         public bool IsFull()
468         {
469             if ((front == -1 && rear == maxsize - 1) || (rear + 1) % maxsize == front)
470                 return true;
471             else
472                 return false;
473         }
474
475         //清空循环顺序列表
476         public void Clear()
477         {
478             front = rear = -1;
479         }
480
481         //判断循环顺序队列是否为空
482         public bool IsEmpty()
483         {
484             if (front == rear)
485                 return true;
486             else
487                 return false;
488         }
489
490         //入队操作
491         public void EnQueue(T elem)
492         {
493             if (IsFull())
494             {
495                 Console.WriteLine("Queue is Full !");
496                 return;
497             }
498             rear = (rear + 1) % maxsize;
499             data[rear] = elem;
500         }
501
502         //出队操作
503         public T DeQueue()
504         {
505             if (IsEmpty())
506             {
507                 Console.WriteLine("Queue is Empty !");
508                 return default(T);
509             }
510             front = (front + 1) % maxsize;
511             return data[front];
512         }
513
514         //获取对头数据元素
515         public T GetFront()
516         {
517             if (IsEmpty())
518             {
519                 Console.WriteLine("Queue is Empty !");
520                 return default(T);
521             }
522             return data[(front + 1) % maxsize];//front从-1开始
523         }
524
525         //求循环顺序队列的长度
526         public int GetLength()
527         {
528             return (rear - front + maxsize) % maxsize;
529         }
530     }
531
532
533     /// <summary>
534     /// 哈夫曼树结点类
535     /// </summary>
536     public class HNode
537     {
538         private int weight;          //结点权值
539         private int lChild;          //左孩子结点
540         private int rChild;          //右孩子结点
541         private int parent;          //父结点
542
543         public int Weight
544         {
545             get { return weight; }
546             set { weight = value; }
547         }
548
549         public int LChild
550         {
551             get { return lChild; }
552             set { lChild = value; }
553         }
554
555         public int RChild
556         {
557             get { return rChild; }
558             set { rChild = value; }
559         }
560
561         public int Parent
562         {
563             get { return parent; }
564             set { parent = value; }
565         }
566
567         public HNode()
568         {
569             weight = 0;
570             lChild = -1;
571             rChild = -1;
572             parent = -1;
573         }
574     }
575 class BinaryTree
576     {
577
578         static void Main(string[] args)
579         {
580             LinkBinarySearchTree bs = new LinkBinarySearchTree();
581             while (true)
582             {
583                 //菜单
584                 Console.WriteLine("\nMenu");
585                 Console.WriteLine("1.创建二叉搜索树");
586                 Console.WriteLine("2.执行中序遍历");
587                 Console.WriteLine("3.执行先序遍历");
588                 Console.WriteLine("4.执行后序遍历");
589                 Console.WriteLine("5.显示搜索一个结点的路径");
590                 Console.WriteLine("6.exit");
591
592                 Console.WriteLine("\n输入你的选择(1-5)");
593                 char ch = Convert.ToChar(Console.ReadLine());
594                 Console.WriteLine();
595
596                 switch (ch)
597                 {
598                     case ‘1‘:
599                         {
600                             int key, offset;
601                             string flag;
602                             do
603                             {
604                                 Console.WriteLine("请输入键:");
605                                 key = Convert.ToInt32(Console.ReadLine());
606                                 Console.WriteLine("请输入位置:");
607                                 offset = Convert.ToInt32(Console.ReadLine());
608                                 indexnode element = new indexnode(key, offset);
609                                 bs.insert(element);
610                                 Console.WriteLine("继续添加新的结点(Y/N)?");
611                                 flag = Console.ReadLine();
612                             } while (flag == "Y" || flag == "y");
613                         }
614                         break;
615                     case ‘2‘:
616                         {
617                             bs.inorderS(bs.Head);
618                         }
619                         break;
620                     case ‘3‘:
621                         {
622                             bs.preorderS(bs.Head);
623                         }
624                         break;
625                     case ‘4‘:
626                         {
627                             bs.postorderS(bs.Head);
628                         }
629                         break;
630                     case ‘5‘:
631                         {
632                             int key;
633                             Console.WriteLine("请输入键");
634                             key = Convert.ToInt32(Console.ReadLine());
635                             bs.find(key);
636                         }
637                         break;
638                     case ‘6‘:
639                         return;
640                     default:
641                         {
642                             Console.WriteLine("Invalid option");
643                             break;
644                         }
645                 }
646             }
647         }
648 }
时间: 2024-11-15 00:32:43

C#实现二叉树 二叉链表结构的相关文章

二叉树-------二叉链表实现

1 #include <stdio.h> 2 #include <stdlib.h> 3 typedef char TelemType; 4 5 typedef struct BinTree{ 6 TelemType data; 7 struct BinTree *LChild; 8 struct BinTree *RChild; 9 }BinaryTree; 10 11 // 12 13 14 BinaryTree* create_BinaryTree(BinaryTree *T

二叉链表存储二叉树

链式存储结构 二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系. 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址.其结点结构为: 其中,data域存放某结点的数据信息:lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示).利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,如图5-8所示. (a) 一棵二叉树 

二叉树的链式存储结构----二叉链表

头文件:head.h #include<string.h> #include<ctype.h> #include<malloc.h> /* malloc()等 */ #include<limits.h> /* INT_MAX等 */ #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<stdlib.h> /* atoi() */ #include<io.h> /* eof()

二叉树的链式存储结构--二叉链表

1 二叉树的链式存储结构 //二叉链表的结点结构定义 typedef struct BiTNode { int data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode; typedef struct BiTNode *BiTree; 结构示意图如下: 2 二叉树的遍历方法 (1)前序遍历:先访问根结,然后前序遍历左子树,再前序遍历右子树. (2)

_DataStructure_C_Impl:二叉树的二叉链表存储结构

// _DataStructure_C_Impl: #include<stdio.h> #include<stdlib.h> #define MaxSize 100 typedef char DataType; typedef struct Node{ //二叉链表存储结构类型定义 DataType data; //数据域 struct Node *lchild; //指向左孩子结点 struct Node *rchild; //指向右孩子结点 }*BiTree,BitNode;

二叉树的二叉链表存储结构

一.二叉树的二叉链表存储结构 二叉树的二叉链表存储结构及其操作应用广泛,各大IT公司面试的时候都很喜欢考察二叉树的奇异操作,但是万变不离其宗,只要熟练掌握二叉树的二叉链表存储结构及其基本操作,其它奇异操作根据需要进行变换即可.如下所示: typedef char TElemType; TElemType Nil = ' '; typedef struct BiTNode { TElemType data; // 结点的值 BiTNode *lchild, *rchild; // 左右孩子指针 }

二叉树的二叉链表存储结构及C++实现

前言:存储二叉树的关键是如何表示结点之间的逻辑关系,也就是双亲和孩子之间的关系.在具体应用中,可能要求从任一结点能直接访问到它的孩子. 一.二叉链表 二叉树一般多采用二叉链表(binary linked list)存储,其基本思想是:令二叉树的每一个结点对应一个链表结点链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针.二叉链表的结点结构如下图所示: 二叉树结点结构 lchild data rchild 其中,data为数据域,存放该结点的数据信息: lchild为左指针域

二叉树的二叉链表表示和实现

二叉树的二叉链表存储结构 typedef struct BiTNode { TElemType data; BiTNode * lchild, *rchild;//左右孩子指针 }BiTNode, * BiTree; 二叉链表的22个基本操作 #define ClearBiTree DestroyBiTree//清空二叉树和销毁二叉树的操作一样 void InitBiTree(BiTree &T){ T = NULL; } void DestroyBiTree(BiTree &T){ if

c使用二叉链表创建二叉树遇到的一些疑问和思考

二叉链表存储二叉树 学习的时候参考的是<大话数据结构>,书中是这样定义的 typedef char TElemType; typedef struct BiTNode { TElemType data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; 结构是这样的,每个节点都存储着当前节点的值,还存储着指向左节点的指针和右节点的指针 typedef 是干什么的 typedef 可以用来定义真实的类型名 一开始我不理解 typedef stru