二叉树的创建:
namespace BinaryTree
{
/// <summary>
/// 二叉树的存储结构类
/// </summary>
/// <typeparam name="T"></typeparam>
public class Node<T>
{
public T Data { get; set; } //数据域(结点数据)
public Node<T> LeftChild { get; set; } //左孩子
public Node<T> RightChild { get; set; } //右孩子
//构造器
public Node(T value, Node<T> lChild, Node<T> rChild)
{
this.Data = value;
this.LeftChild = lChild;
this.RightChild = rChild;
}
//构造器
public Node(Node<T> lChild, Node<T> rChild)
{
this.Data = default(T);
this.LeftChild = lChild;
this.RightChild = rChild;
}
//构造器
public Node(T value)
{
this.Data = value;
this.LeftChild = null;
this.RightChild = null;
}
}
/// <summary>
/// 不带头结点的二叉树的二叉链表的类 BiTree<T>
/// </summary>
/// <typeparam name="T"></typeparam>
public class BiTree<T>
{
public Node<T> Head{get;set;} //头引用
//构造器
public BiTree()
{
this.Head = null;
}
//构造器
public BiTree(T value)
{
Node<T> p = new Node<T>(value);
this.Head = p;
}
//构造器
public BiTree(T val, Node<T> lp, Node<T> rp)
{
Node<T> p = new Node<T>(val, lp, rp);
this.Head = p;
}
//判断是否是空二叉树
public bool IsEmpty()
{
if(this.Head ==null)
return true;
else
return false;
}
//获取根结点
public Node<T> Root()
{
return this.Head;
}
/// <summary>
/// 获取结点的左孩子结点
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public Node<T> GetLeftChild(Node<T> p)
{
return p.LeftChild;
}
/// <summary>
/// 获取结点的右孩子结点
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public Node<T> GetRightChild(Node<T> p)
{
return p.RightChild;
}
/// <summary>
/// 将结点p的左子树插入值为 val的新结点.
/// 原来的左子树成为新结点的左子树.
/// </summary>
/// <param name="value"></param>
/// <param name="p"></param>
public void InsertLeftChild(T value,Node<T> p)
{
Node<T> temp = new Node<T>(value);
temp.LeftChild = p.LeftChild;
p.LeftChild = temp;
}
//将结点p的右子树插入值为 val的新结点,
//原来的右子树成为新结点的右子树.
public void InsertRightChild(T value, Node<T> p)
{
Node<T> temp = new Node<T>(value);
//原来的右子树成为新结点的右子树
temp.RightChild = p.RightChild;
//p的右孩子为新结点
p.RightChild = temp;
}
/// <summary>
/// 若 p 非空, 删除 p 的左子树
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public Node<T> DeleteLeft(Node<T> p)
{
if(p ==null || p.LeftChild ==null)
{
return null;
}
Node<T> temp = p.LeftChild;
temp.LeftChild = null;
return temp;
}
/// <summary>
/// 若 p 非空, 删除 p 的右子树
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public Node<T> DeleteRight(Node<T> p)
{
if ((p == null) || (p.RightChild == null))
{
return null;
}
Node<T> temp = p.RightChild;
p.RightChild = null;
return temp;
}
/// <summary>
/// 判断是否是叶子结点
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public bool IsLeaf(Node<T> p)
{
if ((p != null) && (p.LeftChild == null) && (p.RightChild == 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.LeftChild);
//第三步: 遍历右子树
PreOrder(root.RightChild);
}
//中序遍历(LDR), 思想是: 首先中序遍历结点的左子树,
//然后访问根结点, 最后中序遍历其右子树
//结果为: H DI B E J E A F C G
public void InOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}
//中序遍历左子树
InOrder(root.LeftChild);
//处理根结点,注: 这时的根结点指每一个可以作为父结点的结点.
Console.WriteLine("{0}", root.Data);
//中序遍历右子树.
InOrder(root.RightChild);
}
//后序遍历(LRD): 基本思想是: 首先遍历根结点的左子树,
//然后后后序遍历根结点的右子树, 最后访问根结点
//结果为: H I D J E B F G C A
public void PostOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}
//后序遍历左子树
PostOrder(root.LeftChild);
//后序遍历右子树
PostOrder(root.RightChild);
//处理根结点
Console.WriteLine("{0}", root.Data);
}
//(4).层序遍历(Level Order)
//思想: 由于层次遍历结点的顺序是先遇到的结点先访问,
//与队列操作的顺序相同.
//所以, 在进行层次遍历时, 设置一个队列, 将根结点引用入队,
//当队列非空时, 循环执行以下三步:
//(1).从队列中取出一个结点引用, 并访问该结点.
//(2).若该结点的左子树非空, 将该结点的左子树引用入队;
//(3).若该结点的右子树非空, 将该结点的右子树引用入队;
public void LevelOrder(Node<T> root)
{
//根结点为空
if (root == null)
{
return;
}
//设置一个队列保存层序遍历的结点
//...此处需要引用到队列的定义类与操作类, 暂略.
}
}
}
class Program
{
static void Main(string[] args)
{
Node<string>[] node = new Node<string>[8];
//建立结点
node[0] = new Node<string>("A");
node[1] = new Node<string>("B");
node[2] = new Node<string>("C");
node[3] = new Node<string>("D");
node[4] = new Node<string>("E");
node[5] = new Node<string>("F");
node[6] = new Node<string>("G");
node[7] = new Node<string>("H");
//运用层次遍历二叉树的思想,构造一个已知的二叉树
BiTree<string>[] biTree = new BiTree<string>[8];
biTree[0] = new BiTree<string>("R"); //根结点
biTree[0].Head.LeftChild = node[0];
biTree[0].Head.RightChild = node[1];
biTree[1] = new BiTree<string>("r1");
biTree[1].Head.LeftChild = node[2];
biTree[1].Head.RightChild = node[3];
biTree[2] = new BiTree<string>("r2");
biTree[2].Head.LeftChild = node[4];
biTree[2].Head.RightChild = node[5];
biTree[3] = new BiTree<string>("r3");
biTree[3].Head.LeftChild = node[6];
biTree[3].Head.RightChild = node[7];
//biTree[3].Head.RightChild = biTree[6].Head;
//biTree[4].Head.RightChild = biTree[7].Head;
biTree[0].InOrder(biTree[1].Head);
Console.Read();
}
}
参考:http://www.csharpwin.com/csharpspace/2412.shtml
http://www.cnblogs.com/ppchouyou/archive/2008/07/18/1245819.html
http://tech.sina.com.cn/s/2008-06-20/1017701850.shtml
http://www.yqdown.com/chengxukaifa/CC/28584_3.htm