`

C#实现二叉树(三元素式)及二叉树遍历的四种方法

阅读更多

C#实现二叉树(三元素式)及二叉树遍历的四种方法

using System;
using System.Collections.Generic;
using System.Text;

namespace binaryTree
{
class Program
{
static void Main(string[] args)
{

//用户操作
}
}

//定义: 二叉树的存储结构类
public class Node<T>
{
private T data; //数据域
private Node<T> lChild; //左孩子
private Node<T> rChild; //右孩子

//构造器
public Node(T val, Node<T> lp, Node<T> rp)
{
data = val;
lChild = lp;
rChild = rp;
}

//构造器
public Node(Node<T> lp, Node<T> rp)
{
data = default(T);
lChild = lp;
rChild = rp;
}

//构造器
public Node(T val)
{
data = val;
lChild = null;
rChild = null;
}

//构造器
public Node(T val)
{
data = default(T);
lChild = null;
rChild = null;
}

//数据属性
public T Data
{
get
{
return data;
}
set
{
data = value;
}
}

//左孩子属性
public Node<T> LChild
{
get
{
return lChild;
}
set
{
lChild = value;
}
}

//右孩子属性
public Node<T> RChild
{
get
{
return rChild;
}
set
{
rChild = value;
}
}
}


//不带头结点的二叉树的二叉链表的类 BiTree<T>
public class BiTree<T>
{
private Node<T> head; //头引用

//构造器
public BiTree()
{
head = null;
}

//构造器
public BiTree(T val)
{
Node<T> p = new Node<T>(val);
head = p;
}

//构造器
public BiTree(T val, Node<T> lp, Node<T> rp)
{
Node<T> p = new Node<T>(val, lp, rp);
head = p;
}

//头引用属性
public Node<T> Head
{
get
{
return head;
}
set
{
head = value;
}
}

//判断是否是空二叉树
public bool IsEmpty()
{
if (head == null)
{
return true;
}
else
{
return false;
}
}

//获取根结点
public Node<T> Root()
{
return head;
}

//获取结点的左孩子结点
public Node<T> GetLChild(Node<T> p)
{
return p.LChild;
}

//获取结点的右孩子结点
public Node<T> GetRChild(Node<T> p)
{
return p.RChild;
}

//将结点p的左子树插入值为 val的新结点.
//原来的左子树成为新结点的左子树.
public void InsertL(T val, Node<T> p)
{
Node<T> tmp = new Node<T>(val);
tmp.LChild = p.LChild; //原来的左子树成为新结点的左子树.
p.LChild = tmp; //p的左子孩子为新结点.
}

//将结点p的右子树插入值为 val的新结点,
//原来的右子树成为新结点的右子树.
public void InsertR(T val, Node<T> p)
{
Node<T> tmp = new Node<T>(val);
tmp.RChild = p.RChild; //原来的右子树成为新结点的右子树
p.RChild = tmp; //p的右孩子为新结点
}

//若 p 非空, 删除 p 的左子树
public Node<T> DeleteL(Node<T> p)
{
if(( p==null || (p.LChild==null))
{
return null;
}

Node<T> tmp = p.LChild;
p.LChild=null;

return tmp;
}

//若 p 非空, 删除 p 的右子树
public Node<T> DeleteR(Node<T> p)
{
if ((p == null) || (p.RChild == null))
{
return null;
}

Node<T> tmp = p.RChild;
p.RChild = null;

return tmp;
}

//判断是否是叶子结点
public bool IsLeaf(Node<T> p)
{
if ((p != null) && (p.LChild == null) && (p.RChild == null))
{
return true;
}
else
{
return false;
}
}


//树的遍历: 由于树的定义是递归的, 所以遍历算法也彩递归实现
//原始顺序为: A B C D E F G H I J (原则是 从小到下, 从左到右)
//1.先序遍历(DLR), 思想是: 首先访问根结点, 然后先序遍历其左子树, 最后先遍历其右子树.
//结果是: A B D H I E J C F G
public void PreOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}

//第一步: 处理根结点
Console.WriteLine("{0}", root.Data);

//第二步: 遍历左子树
PreOrder(root.LChild);

//第三步: 遍历右子树
PreOrder(root.RChild);
}


//中序遍历(LDR), 思想是: 首先中序遍历结点的左子树, 然后访问根结点, 最后中序遍历其右子树
//结果为: H DI B E J E A F C G
public void InOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}

//中序遍历左子树
InOrder(root.LChild);

//处理根结点,注: 这时的根结点指每一个可以作为父结点的结点.
Console.WriteLine("{0}", root.Data);

//中序遍历右子树.
InOrder(root.RChild);
}


//后序遍历(LRD): 基本思想是: 首先遍历根结点的左子树, 然后后后序遍历根结点的右子树, 最后访问根结点
//结果为: H I D J E B F G C A
public void PostOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}

//后序遍历左子树
PostOrder(root.LChild);

//后序遍历右子树
PostOrder(root.RChild);

//处理根结点
Console.WriteLine("{0}", root.Data);

}


//(4).层序遍历(Level Order)
//思想: 由于层次遍历结点的顺序是 先遇到的结点先访问, 与队列操作的顺序相同.
//所以, 在进行层次遍历时, 设置一个队列, 将根结点引用入队, 当队列非空时, 循环执行以下三步:
//(1).从队列中取出一个结点引用, 并访问该结点.
//(2).若该结点的左子树非空, 将该结点的左子树引用入队;
//(3).若该结点的右子树非空, 将该结点的右子树引用入队;
public void LevelOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}

//设置一个队列保存层序遍历的结点
//...此处需要引用到队列的定义类与操作类, 暂略.
}
}

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics