zoukankan      html  css  js  c++  java
  • 【万丈高楼平地起 第三季 C#实现二叉树操作】

    本文接上一篇【万丈高楼平地起 第二季 队列和栈】继续说明如何用C#语言实现二叉树的操作。

    四、树
         
    链表、堆栈和队列都是线性结构(即序列)。树是一种特殊的非线性二维数据机构。树节点包含两个或两个以上的链接。工作中主要应用的二叉树——每个节点都有两个链接(其中可有一个或两个链接为null)。根节点是树的第一个节点。左孩子(left child)是左子树的第一个节点,右孩子(right child )是右子树的第一个节点。属于相同节点的子节点成为兄弟节点(siblings)。没有子节点的节点成为叶子节点。计算机科学家常常用根节点在上、叶子节点的方式画出一棵树——同树的自然生长方向恰好相反。


    特殊二叉树——二叉查找树
    二叉查找树(没有重复的节点值)的特征是:左子树中任何值都小于父节点的值,右子树中任何值都大于父节点的值。


    构建二叉树、前序、中序、后序遍历二叉树  BinaryTreeLibrary.cs

    View Code
      1 using System;
    2
    3 namespace BinaryTreeLibrary
    4 {
    5 /// <summary>
    6 /// 定义TreeNode类
    7 /// </summary>
    8 class TreeNode
    9 {
    10 private TreeNode leftNode;
    11 private int data;
    12 private TreeNode rightNode;
    13
    14 /// <summary>
    15 /// 初始化数据,构造一个叶子节点
    16 /// </summary>
    17 /// <param name="nodeData"></param>
    18 public TreeNode(int nodeData)
    19 {
    20 data = nodeData;
    21 leftNode = rightNode = null;
    22 }
    23
    24 /// <summary>
    25 /// 左节点
    26 /// </summary>
    27 public TreeNode LeftNode
    28 {
    29 get
    30 {
    31 return leftNode;
    32 }
    33 set
    34 {
    35 leftNode = value;
    36 }
    37 }
    38
    39 /// <summary>
    40 /// Data数据节点
    41 /// </summary>
    42 public int Data
    43 {
    44 get
    45 {
    46 return data;
    47 }
    48 set
    49 {
    50 data = value;
    51 }
    52 }
    53
    54 public TreeNode RightNode
    55 {
    56 get
    57 {
    58 return rightNode;
    59 }
    60 set
    61 {
    62 rightNode = value;
    63 }
    64 }
    65
    66 /// <summary>
    67 /// 在包含节点的二叉树中插入TreeNode
    68 /// </summary>
    69 /// <param name="insertValue"></param>
    70 public void Insert(int insertValue)
    71 {
    72 // 在左子树中插入数据
    73 if (insertValue < data)
    74 {
    75 // 如果没有左子树就构建一个叶子节点
    76 if (leftNode == null)
    77 {
    78 leftNode = new TreeNode(insertValue);
    79 }
    80 else
    81 {
    82 // 遍历左子树
    83 leftNode.Insert(insertValue);
    84 }
    85 }
    86 // 在右子树中插入数据
    87 else if (insertValue > data)
    88 {
    89 // 如果没有右子树就构建一个叶子节点
    90 if (rightNode == null)
    91 {
    92 rightNode = new TreeNode(insertValue);
    93 }
    94 else
    95 {
    96 // 遍历右子树
    97 rightNode.Insert(insertValue);
    98 }
    99 }
    100 }// end insert method
    101
    102 }// end class TreeNode
    103
    104 /// <summary>
    105 /// 类Tree定义
    106 /// </summary>
    107 public class Tree
    108 {
    109 // 整个类操作的是 TreeNode 类的对象
    110 private TreeNode root;
    111
    112 /// <summary>
    113 /// 构建一颗空树
    114 /// </summary>
    115 public Tree()
    116 {
    117 root = null;
    118 }
    119
    120 /// <summary>
    121 /// 将新节点插入到二叉树
    122 /// 如果根节点是空的,就创建根节点
    123 /// 否则,调用insert方法
    124 /// </summary>
    125 /// <param name="insertValue"></param>
    126 public void InsertNode(int insertValue)
    127 {
    128 lock (this)
    129 {
    130 if (root == null)
    131 {
    132 root = new TreeNode(insertValue);
    133 }
    134 else
    135 {
    136 root.Insert(insertValue);
    137 }
    138 }
    139 }
    140
    141 /// <summary>
    142 /// 前序遍历
    143 /// </summary>
    144 public void PreorderTraverse()
    145 {
    146 lock (this)
    147 {
    148 PreorderHelper(root);
    149 }
    150 }
    151
    152
    153 /// <summary>
    154 /// 递归进行前序遍历
    155 /// </summary>
    156 /// <param name="node"></param>
    157 private void PreorderHelper(TreeNode node)
    158 {
    159 if (node == null)
    160 {
    161 return;
    162 }
    163
    164 // 输出 节点 数据
    165 Console.Write(node.Data + " ");
    166
    167 // 遍历左子树
    168 PreorderHelper(node.LeftNode);
    169
    170 // 遍历右子树
    171 PreorderHelper(node.RightNode);
    172 }
    173
    174 /// <summary>
    175 /// 中序遍历
    176 /// </summary>
    177 public void InorderTravese()
    178 {
    179 lock (this)
    180 {
    181 InorderHelper(root);
    182 }
    183 }
    184
    185 /// <summary>
    186 /// 递归进行中序遍历
    187 /// </summary>
    188 /// <param name="node"></param>
    189 private void InorderHelper(TreeNode node)
    190 {
    191 if (node == null)
    192 {
    193 return;
    194 }
    195
    196 // 先 遍历左子树
    197 InorderHelper(node.LeftNode);
    198
    199 // 输出 数据 节点
    200 Console.Write(node.Data + " ");
    201
    202 // 后 遍历右子树
    203 InorderHelper(node.RightNode);
    204
    205 }
    206
    207 /// <summary>
    208 /// 后序遍历
    209 /// </summary>
    210 public void PostorderTravese()
    211 {
    212 lock (this)
    213 {
    214 PostorderHelper(root);
    215 }
    216 }
    217
    218 /// <summary>
    219 /// 递归进行后序遍历
    220 /// </summary>
    221 /// <param name="node"></param>
    222 private void PostorderHelper(TreeNode node)
    223 {
    224 if (node == null)
    225 {
    226 return;
    227 }
    228
    229 // 先 遍历左子树
    230 PostorderHelper(node.LeftNode);
    231
    232 // 再 遍历右子树
    233 PostorderHelper(node.RightNode);
    234
    235 // 输出 数据 节点
    236 Console.Write(node.Data + " ");
    237 }
    238 }// end class Tree
    239 }

      

    Tree类操作TreeNode类的对象。Tree类有一个私有数据成员——root,这是对根节点的引用。

    为保证线程的安全性,Tree类的InsertNode方法首先锁定Tree对象,然后再进行后序是否为空、插入节点等操作。
    方法PreorderTraverse()InorderTraverse()PostorderTraverse()分别调用辅助方法PreorderHelperInorderHelperPostorderHelper方法。

    测试代码,Program.cs

    using System;
    using BinaryTreeLibrary;

    namespace TreeTest
    {
    class Program
    {
    static void Main(string[] args)
    {
    Tree tree
    = new Tree();
    int insertValue;

    Console.WriteLine(
    "Inserting values: ");
    Random random
    = new Random();

    for (int i = 0; i <= 10; i++)
    {
    insertValue
    = random.Next(100);
    Console.Write(insertValue
    + " ");

    tree.InsertNode(insertValue);
    }

    // 前序遍历
    Console.Write("\n\n 前序遍历:");
    tree.PreorderTraverse();

    // 中序遍历
    Console.Write("\n\n 中序遍历:");
    tree.InorderTravese();

    // 后序遍历
    Console.Write("\n\n 后序遍历:");
    tree.PostorderTravese();

    Console.ReadKey();
    }
    }
    }

      

    至此,二叉查找树测试完毕!

  • 相关阅读:
    错题
    URL和URI区别
    适配器
    JAVA 反射机制
    JAVA 面试题
    JAVA 继承
    多态 JAVA
    Java面向对象编辑
    [LeetCode] Merge k Sorted Lists
    [LeetCode] Valid Palindrome
  • 原文地址:https://www.cnblogs.com/fanyong/p/2176379.html
Copyright © 2011-2022 走看看