C#创建以及操作二叉树

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C#创建以及操作⼆叉树
这是我⽤C#编写的关于⼆叉树的⼀个类,它是⼀个Windows程序的⼀部分(⽤于图形化显⽰⼀棵⼆叉树,并能插⼊、寻找、删除任意节点,最后还可以将⼀棵⾮平衡的⼆叉树平衡化)。

下⾯仅对其中的两个函数做下说明:
private void Insert(TreeNode root, int num) //⽤⼀般的要求建⽴⼀棵⼆叉树
private TreeNode AVLTreeInsertNode(int num, ref TreeNode root) //按照动态平衡的要求建⽴⼀棵⼆叉树
using System.Drawing;
using System.Collections;
namespace nsBinaryTree
{
// 定义树节点类
public class TreeNode
{
private int data; // 节点数据
public TreeNode left_child; // 左⼦⼥
public TreeNode right_child; // 右⼦⼥
public TreeNode parent; // ⽗节点
// 节点在树中的⾼度,平衡处理时,⽤节点在树中的⾼度代替平衡因⼦
public int Height;
// data访问器
public int Data
{
get
{
return data;
}
set
{
data = value;
}
}
// 左⼦⼥访问器
public TreeNode LeftChild
{
get
{
return left_child;
}
set
{
left_child = value;
}
}
// 右⼦⼥访问器
public TreeNode RightChild
{
get
{
return right_child;
}
set
{
right_child = value;
}
}
// ⽗节点访问器
get
{
return parent;
}
set
{
parent = value;
}
}
// 构造函数,初始化左右⼦⼥为空 public TreeNode()
{
data = 0;
left_child = null;
right_child = null;
parent = null;
}
}
// 定义⼆叉树类
public class BinaryTree
{
public TreeNode root; //根节点 // 根节点的访问器
public TreeNode Root
{
get
{
return root;
}
set
{
root = value;
}
}
// 构造函数
public BinaryTree()
{
root = null;
}
// 判断树是否为空
public bool IsNullOrEmpty()
{
if (root == null)
{
return true;
}
else
{
return false;
}
}
// Insert a node to the tree.
public void Insert(int num)
{
if (root == null)
{
root = new TreeNode();
root.Data = num;
root.parent = null;
}
Insert(root, num);
}
}
// 插⼊元素,重载函数
private void Insert(TreeNode root, int num)
{
if (num == root.Data)
{
return;
}
else if (num < root.Data)
{
if (root.LeftChild == null)
{
TreeNode temp_node = new TreeNode();
temp_node.Data = num;
temp_node.Parent = root;
root.LeftChild = temp_node;
}
else
{
Insert(root.LeftChild, num);
}
}
else
{
if (root.RightChild == null)
{
TreeNode temp_node = new TreeNode();
temp_node.Data = num;
temp_node.Parent = root;
root.RightChild = temp_node;
}
else
{
Insert(root.RightChild, num);
}
}
}
// 查找是否存在某⼀个数值,如果存在,返回该节点,否则返回null public TreeNode Search(int num)
{
TreeNode searched_node = new TreeNode();
searched_node = Search(root, num);
return searched_node;
}
// 查找是否存在该元素,重载函数
private TreeNode Search(TreeNode root, int num)
{
TreeNode searched_node = new TreeNode();
if (root.Data == num)
{
searched_node = root;
}
else
{
if (num < root.Data)
{
if (root.LeftChild != null)
{
}
}
else
{
if (root.RightChild != null)
{
searched_node = Search(root.RightChild, num);
}
}
}
return searched_node;
}
// 遍历⼆叉树,从⽽设置其所有节点的Brush属性为默认值
public void SetTreeNodeBrush()
{
SetTreeNodeBrush(root);
}
// 前序遍历,重载函数
private void SetTreeNodeBrush(TreeNode root)
{
if (root != null)
{
// TODO: 添加遍历要做的事,⽐如我希望在PictureBox中绘制节点,那么可以在这⾥设置节点的画刷属性: //root.Brush = new SolidBrush(Color.Turquoise); //重新设置节点的画刷
if (root.LeftChild != null)
{
SetTreeNodeBrush(root.LeftChild);
}
if (root.RightChild != null)
{
SetTreeNodeBrush(root.RightChild);
}
}
}
// 获得该节点最⼩右⼦⼥(另⼀种⽅法是取它的最⼤左⼦⼥),⽤于删除节点
TreeNode MinRightChild(TreeNode parent)
{
TreeNode temp = parent;
while (temp != null)
{
if (temp.LeftChild == null)
{
return temp;
}
else
{
temp = temp.LeftChild;
}
}
return null;
}
// 删除节点
public void DeleteNode(int num)
{
if (root == null)
{
return;
}
else if(root.Data == num)
TreeNode tmp = MinRightChild(root.RightChild);
if(tmp == null)
{
root = root.LeftChild;
}
else
{
root.Data = tmp.Data;
DeleteNode(root, root.RightChild, 1, tmp.Data);
}
}
else if (root.Data < num)
{
DeleteNode(root, root.RightChild, 1, num);
}
else
{
DeleteNode(root, root.LeftChild, 0, num);
}
}
// 删除节点,重载函数
private void DeleteNode(TreeNode parent, TreeNode cur, int direction, int num) {
if (cur.Data == num)
{
if (cur.LeftChild == null)
{
if (direction == 0)
{
parent.LeftChild = cur.RightChild;
}
else
{
parent.RightChild = cur.RightChild;
}
}
else if (cur.RightChild == null)
{
if (direction == 0)
{
parent.LeftChild = cur.LeftChild;
}
else
{
parent.RightChild = cur.LeftChild;
}
}
else
{
TreeNode tmp = MinRightChild(cur.RightChild);
cur.Data = tmp.Data;
DeleteNode(cur, cur.RightChild, 1, tmp.Data);
}
}
else if (cur.Data > num)
{
DeleteNode(cur, cur.LeftChild, 0, num);
}
else
{
DeleteNode(cur, cur.RightChild, 1, num);
}
}
// 求树的深度
private int TreeHeight(TreeNode root)
if (root == null)
{
return 0;
}
else
{
int left_depth = TreeHeight(root.left_child);
int right_depth = TreeHeight(root.right_child);
if (left_depth > right_depth)
{
return left_depth + 1;
}
else
{
return right_depth + 1;
}
}
}
// 判断⼀棵树是否为平衡⼆叉树
public bool IsBalance()
{
return IsBalance(root);
}
// 判断⼀棵树是否为平衡⼆叉树,重载函数
private bool IsBalance(TreeNode root)
{
if (root == null)
{
return true;
}
int dis = TreeHeight(root.left_child) - TreeHeight(root.right_child);
if (dis > 1 || dis < -1)
{
return false;
}
else
{
return IsBalance(root.left_child) && IsBalance(root.right_child);
}
}
// 平衡⼆叉树
public void Balance()
{
Balance(ref root);
}
// 平衡⼆叉树,重载函数
// ⼤体过程:先将树的所有节点Data值存⼊到⼀个数组中,然后再按照平衡⼆叉树的要求逐个插⼊Data,从⽽得到平衡⼆叉树 private void Balance(ref TreeNode root)
{
if (this.IsBalance() == true) // 判断树是否已经平衡
{
return;
}
else
{
ArrayList array_list = new ArrayList();
SaveTreeNode(root, array_list); //将树内所有结点的Data值存⼊到⼀个ArrayList中
BinaryTree btree = new BinaryTree();
for (int i = 0; i < array_list.Count; i++)
root = AVLTreeInsertNode((int)array_list[i], ref btree.root);
}
}
}
// 通过前序遍历的⽅式,将树内所有结点的Data值存⼊到⼀个ArrayList中,为建⽴平衡⼆叉树做准备 private void SaveTreeNode(TreeNode root, ArrayList array_list)
{
if (root != null)
{
array_list.Add(root.Data);
if (root.left_child != null)
{
SaveTreeNode(root.left_child, array_list);
}
if (root.right_child != null)
{
SaveTreeNode(root.right_child, array_list);
}
}
}
// 按平衡⼆叉树的要求插⼊节点
private TreeNode AVLTreeInsertNode(int num, ref TreeNode root)
{
if (root == null)
{
root = new TreeNode();
root.Data = num;
root.Height = 0;
root.left_child = root.right_child = null;
}
else if (num < root.Data) // 插⼊到左⼦树中
{
root.left_child = AVLTreeInsertNode(num, ref root.left_child);
if (TreeHeight(root.left_child) - TreeHeight(root.right_child) == 2) // AVL树不平衡
{
if (num < root.left_child.Data)
{
root = SingleRotateWithLeft(root); // 插⼊到了左⼦树左边, 做单旋转
}
else
{
root = DoubleRotateWithLeft(root); // 插⼊到了左⼦树右边, 做双旋转
}
}
}
else if (num > root.Data) // 插⼊到右⼦树中
{
root.right_child = AVLTreeInsertNode(num, ref root.right_child);
if (TreeHeight(root.right_child) - TreeHeight(root.left_child) == 2) // AVL树不平衡
{
if (num > root.right_child.Data)
{
root = SingleRotateWithRight(root); // 插⼊到了右⼦树右边, 做单旋转
}
else
{
root = DoubleRotateWithRight(root); // 插⼊到了右⼦树左边, 做双旋转
}
}
}
root.Height = Max(TreeHeight(root.left_child), TreeHeight(root.right_child)) + 1;
}
// 左单旋转
private TreeNode SingleRotateWithLeft(TreeNode root)
{
TreeNode node = new TreeNode();
node = root.left_child;
root.left_child = node.right_child;
node.right_child = root;
// 结点的位置改变了, 更新其⾼度值
root.Height = Max(TreeHeight(root.left_child), TreeHeight(root.right_child)) + 1; node.Height = Max(TreeHeight(node.left_child), root.Height) + 1;
return node;
}
// 右单旋转
private TreeNode SingleRotateWithRight(TreeNode root)
{
TreeNode node = new TreeNode();
node = root.right_child;
root.right_child = node.left_child;
node.left_child = root;
// 结点的位置改变了, 更新其⾼度值
root.Height = Max(TreeHeight(root.left_child), TreeHeight(root.right_child)) + 1; node.Height = Max(TreeHeight(node.right_child), root.Height) + 1;
return node;
}
// 先左后右双旋转
private TreeNode DoubleRotateWithLeft(TreeNode root)
{
root.left_child = SingleRotateWithRight(root.left_child);
return SingleRotateWithLeft( root);
}
// 先右后左双旋转
private TreeNode DoubleRotateWithRight(TreeNode root)
{
root.right_child = SingleRotateWithLeft(root.right_child);
return SingleRotateWithRight(root);
}
// 求两个整数中较⼤的数
private int Max(int a, int b)
{
return a > b ? a : b;
}
// 删除树
public void DeleteTree()
{
DeleteTree(ref root);
}
// 删除树,重载函数
private void DeleteTree(ref TreeNode root)
{
if (root != null)
{
if (root.LeftChild != null)
{
}
if (root.RightChild != null)
{
DeleteTree(ref root.right_child);
}
if (root.LeftChild != null && root.Parent != null) {
root.Parent.left_child = null;
}
if (root.RightChild != null && root.Parent != null) {
root.Parent.right_child = null;
}
root = null;
}
}
}
}。

相关文档
最新文档