zoukankan      html  css  js  c++  java
  • 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     }
    
    
  • 相关阅读:
    Cesium 模拟卫星扫描
    SQL Server配置管理器”远程过程调用失败“的问题解决
    Windows系统查看端口占用、结束进程方法和命令
    Cesium 遥感卫星影像推送效果绘制
    Nginx 发布本地后台端口
    js 产生16位随机字符串
    vscode powershell/gitbash g++ : 无法将“g++”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 1
    安装Tomcat服务器以及错误汇总(tomcat8.0、jdk8)
    Windows 8及以上系统安装好SQL Server 2008之后找不到SQL Server配置管理器的问题
    mysql 利用binlog增量备份,还原实例
  • 原文地址:https://www.cnblogs.com/JiYF/p/7048297.html
Copyright © 2011-2022 走看看