二叉树中的先序,中序,后续遍历很容易让人迷糊,记录一下概念。
遍历是将二叉树中的结点信息由非线性排列变为某种意义上的线性排列。也就是说,遍历操作使非线性结构线性化。
一棵二叉树由根结点、左子树和右子树三部分组成,若规定 D、L、R 分别代表遍历根结点、遍历左子树、遍历右子树,则二叉树的遍历方式有 6 种:DLR、DRL、LDR、LRD、RDL、RLD。由于先遍历左子树和先遍历右子树在算法设计上没有本质区别,所以,只讨论三种方式:DLR(先序 遍历)、LDR(中序遍历)和 LRD(后序遍历)。
我们对如下树进行先序遍历(DLR)、中序遍历(LDR)和 后序遍历(LRD),大家试着写出各种遍历后的字母排列后再看答案。
1、先序遍历(DLR)
先序遍历的基本思想是:首先访问根结点,然后先序遍历其左子树,最后先序遍历其右子树。
![]()
DLR结果A B D H I E J C F G
2、DRL
DRL的基本思想是:首先访问根结点,然后先序遍历其右子树,最后先序遍历其左子树。
![]()
DRL结果A C G F B E J D I H
3、中序遍历(LDR) 中序遍历的基本思想是:首先中序遍历根结点的左子树,然后访问根结点,最后中序遍历其右子树。
![]()
LDR结果H D I B J E A F C G
4、RDL
RDL的基本思想是:首先中序遍历根结点的右子树,然后访问根结点,最后中序遍历其左子树。
![]()
RDL结果G C F A E J B I D H
5、后序遍历(LRD) 后序遍历的基本思想是:首先后序遍历根结点的左子树,然后后序遍历根结点的右子树,最后访问根结点
![]()
LRD结果H I D J E B F G C A
6、RLD
RLD的基本思想是:首先后序遍历根结点的右子树,然后后序遍历根结点的左子树,最后访问根结点
![]()
RLD结果G F C J E I H D B A
![]()
实现二叉树排序,查找/// <summary>
/// 1、选定要排列数组第一个作为跟节点
/// 2、从索引为1的元素开始循环到最后一个,和根节点比较如果 <=根节点 则走根节点的左子节点树直到最后一个节点 ,如果<=最后一个节点 则添加到此节点的左侧,否则添加到此节点的右侧
/// 如果>根节点 则走根节点的右子节点树直到最后一个节点 ,如果<=最后一个节点 则添加到此节点的左侧,否则添加到此节点的右侧
/// 3、将二叉树按照中序遍历打印出字符即为 升序排序
/// </summary>
public class BinaryTreeSort
{ //成员变量
private NodeSort _head; //头指针
private int[] aInt; //用于构造二叉树
public NodeSort Head //头指针
{
get { return _head; }
}
//构造方法
public BinaryTreeSort(int[] arrint)
{
aInt = arrint;
_head = new NodeSort(aInt[0]); //添加头结点
for (int i = 1; i < aInt.Length; i++)
{
Insert(aInt[i]);
}
}
public void Insert(int i)
{
NodeSort newNode = new NodeSort(i);
NodeSort current = _head;
NodeSort parent;
while (true)
{
parent = current;
if (i < current.Value)
{
current = current.Left;
if (current == null)
{
parent.Left = newNode;
break;
}
}
else
{
current = current.Right;
if (current == null)
{
parent.Right = newNode;
break;
}
}
}
}
public void PreOrder(NodeSort NodeSort) //先序遍历
{
if (NodeSort != null)
{
Console.Write(" {0}",NodeSort.ToString()); //打印字符
PreOrder(NodeSort.Left); //递归
PreOrder(NodeSort.Right); //递归
}
}
public void MidOrder(NodeSort NodeSort) //中序遍历
{
if (NodeSort != null)
{
MidOrder(NodeSort.Left); //递归
Console.Write(" {0}", NodeSort.ToString()); //打印字符
MidOrder(NodeSort.Right); //递归
}
}
public void AfterOrder(NodeSort NodeSort) //后继遍历
{
if (NodeSort != null)
{
AfterOrder(NodeSort.Left); //递归
AfterOrder(NodeSort.Right); //递归
Console.Write(" {0}", NodeSort.ToString()); //打印字符
}
}
public bool Find(int value)
{
return SubFind(_head, value);
}
bool flg = false;
private bool SubFind(NodeSort rootnode, int value)
{
if (rootnode != null)
{
if (value > rootnode.Value)
{
if (!flg)
SubFind(rootnode.Right, value);
}
else if (value < rootnode.Value)
{
if (!flg)
SubFind(rootnode.Left, value);
}
else
{
flg = true;
}
}
return flg;
}
}
public class NodeSort
{
//成员变量
private int _data; //数据
private NodeSort _left; //左孩子
private NodeSort _right; //右孩子
public int Data
{
get { return _data; }
}
public NodeSort Left //左孩子
{
get { return _left; }
set { _left = value; }
}
public NodeSort Right //右孩子
{
get { return _right; }
set { _right = value; }
}
//构造方法
public NodeSort(int data)
{
_data = data;
}
public override string ToString()
{
return _data.ToString();
}
public int Value
{
get
{
return _data;
}
}
}