二叉树前中后序递归/非递归遍历以及按层遍历
2018-03-05 20:54
141 查看
先定义树节点类(TreeNode)和二叉树类(BinaryTree)public class TreeNode<T>
{
public T Data { get; set;}
public TreeNode<T> Parent { get;protected set; }
protected virtual int Deepth
{
get
{
if(Parent!=null)
{
return Parent.Deepth + 1;
}
return 0;
}
}
}
class BinaryTree<T> : TreeNode<T>
{
private BinaryTree<T> _leftTree;
private BinaryTree<T> _rightTree;
public BinaryTree<T> LeftTree
{
get { return _leftTree; }
set
{
if (_leftTree != null)
_leftTree.Parent = null;
_leftTree = value;
if (_leftTree != null)
_leftTree.Parent = this;
}
}
public BinaryTree<T> RightTree
get { return _rightTree; }
set
{
if (_rightTree != null)
_rightTree.Parent = null;
_rightTree = value;
if (_rightTree != null)
_rightTree.Parent = this;
}
}
}
二叉树遍历分为:
前序遍历[b](DLR):访问根节点->前序遍历左子树->前序遍历右子树;[/b]
中序遍历(LDR):中序遍历左子树->访问根节点->中序遍历右子树;
后序遍历(LRD):后序遍历左子树->后序遍历右子树->访问根节点;
按层遍历(Level Travel):先访问所有兄弟节点,再访问所有兄弟节点的所有直接子节点.
------------------------------------割割割割割------------------------------------------------------DLR递归实现
注意:1、这里用Stack存储结果;2、左子树和右子树入栈顺序与DLR不同。
public static T[] LRDTravelNoRecursion<T>(BinaryTree<T> tree)
{
if (tree == null)
return null;
var result = new Stack<T>();
Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>();
stack.Push(tree);
while (stack.Count > 0 )
{
BinaryTree<T> node = stack.Pop();
result.Push(node.Data);
if (node.LeftTree != null)
stack.Push(node.LeftTree);
if (node.RightTree != null)
stack.Push(node.RightTree);
}
return result.ToArray();
}LDR递归实现
{
public T Data { get; set;}
public TreeNode<T> Parent { get;protected set; }
protected virtual int Deepth
{
get
{
if(Parent!=null)
{
return Parent.Deepth + 1;
}
return 0;
}
}
}
class BinaryTree<T> : TreeNode<T>
{
private BinaryTree<T> _leftTree;
private BinaryTree<T> _rightTree;
public BinaryTree<T> LeftTree
{
get { return _leftTree; }
set
{
if (_leftTree != null)
_leftTree.Parent = null;
_leftTree = value;
if (_leftTree != null)
_leftTree.Parent = this;
}
}
public BinaryTree<T> RightTree
get { return _rightTree; }
set
{
if (_rightTree != null)
_rightTree.Parent = null;
_rightTree = value;
if (_rightTree != null)
_rightTree.Parent = this;
}
}
}
二叉树遍历分为:
前序遍历[b](DLR):访问根节点->前序遍历左子树->前序遍历右子树;[/b]
中序遍历(LDR):中序遍历左子树->访问根节点->中序遍历右子树;
后序遍历(LRD):后序遍历左子树->后序遍历右子树->访问根节点;
按层遍历(Level Travel):先访问所有兄弟节点,再访问所有兄弟节点的所有直接子节点.
------------------------------------割割割割割------------------------------------------------------DLR递归实现
public static T[] DLRTravel<T>(BinaryTree<T> tree) { List<T> result = new List<T>(); result.Add(tree.Data); if (tree.LeftTree != null) result.AddRange(DLRTravel(tree.LeftTree)); if (tree.RightTree != null) result.AddRange(DLRTravel(tree.RightTree)); return result.ToArray(); }DLR非递归实现
public static T[] DLRTravelNoRecursion<T>(BinaryTree<T> tree) { if (tree == null) return null; var result = new List<T>(); Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>(); stack.Push(tree); while (stack.Count > 0) { BinaryTree<T> node = stack.Pop(); result.Add(node.Data); if (node.RightTree != null) stack.Push(node.RightTree); if (node.LeftTree != null) stack.Push(node.LeftTree); } return result.ToArray(); }LRD递归实现
public static T[] LRDTravel<T>(BinaryTree<T> tree) { var result = new List<T>(); if (tree.LeftTree != null) result.AddRange(LRDTravel(tree.LeftTree)); if (tree.RightTree != null) result.AddRange(LRDTravel(tree.RightTree)); result.Add(tree.Data); return result.ToArray(); }LRD非递归实现 考虑到LRD实际上就是倒序的DRL,所以我们可以把DLR的非递归实现稍微改下执行顺序,最后把结果反转就行了.
注意:1、这里用Stack存储结果;2、左子树和右子树入栈顺序与DLR不同。
public static T[] LRDTravelNoRecursion<T>(BinaryTree<T> tree)
{
if (tree == null)
return null;
var result = new Stack<T>();
Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>();
stack.Push(tree);
while (stack.Count > 0 )
{
BinaryTree<T> node = stack.Pop();
result.Push(node.Data);
if (node.LeftTree != null)
stack.Push(node.LeftTree);
if (node.RightTree != null)
stack.Push(node.RightTree);
}
return result.ToArray();
}LDR递归实现
public static T[] LDRTravel<T>(BinaryTree<T> tree) { List<T> result = new List<T>(); if (tree.LeftTree != null) result.AddRange(LDRTravel(tree.LeftTree)); result.Add(tree.Data); if (tree.RightTree != null) result.AddRange(LDRTravel(tree.RightTree)); return result.ToArray(); }LDR非递归实现稍显麻烦
public static T[] LDRTravelNoRecursion<T>(BinaryTree<T> tree) { if (tree == null) return null; var result = new List<T>(); Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>(); BinaryTree<T> node = tree; while (stack.Count > 0||node!=null) { while (node != null) { stack.Push(node); if (node.LeftTree != null) node = node.LeftTree; else node = null; } node = stack.Pop(); result.Add(node.Data); if (node.RightTree != null) node = node.RightTree; else node = null; } return result.ToArray(); }按层遍历
public static T[] LevelTravel<T>(BinaryTree<T> tree) { var queue = new Queue<BinaryTree<T>>(); queue.Enqueue(tree); var result = new List<T>(); LevelTravelImpl(queue, result); return result.ToArray(); } /// <summary> /// 二叉树按层遍历递归体 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="queue"></param> /// <param name="result"></param> private static void LevelTravelImpl<T>(Queue<BinaryTree<T>> queue, List<T> result) { if (queue == null || queue.Count == 0) return; var tree = queue.Dequeue(); if (tree.LeftTree != null) { queue.Enqueue(tree.LeftTree); result.Add(tree.LeftTree.Data); } if (tree.RightTree != null) { queue.Enqueue(tree.RightTree); result.Add(tree.RightTree.Data); } LevelTravelImpl(queue, result); }
相关文章推荐
- 二叉树的迭代前中后遍历以及不用栈的遍历C语言
- 二叉树的建立,以及递归前中后序遍历二叉树
- 二叉树的深度优先,广度优先,以及层次遍历算法
- 二叉树的性质极其二叉树的构建、各种遍历以及深度宽度的求解
- 二叉树动态链式创建以及遍历
- 什么是二叉树?以及二叉树如何遍历?
- 二叉树的遍历、查找、插入以及删除
- 二叉树的非递归遍历以及层次遍历(前序、中序、后序)
- C++二叉树之构造拷贝赋值,递归和非递归的前序遍历,中序遍历和后序遍历,以及层序遍历
- 二叉树的遍历(前中后,层次)——legend
- 由先序遍历序列和中序遍历序列恢复二叉树以及统计叶子节点个数和树的深度
- 重建二叉树以及树的遍历
- 二叉树的创建,插入,删除,输出,求高度,求度以及三种遍历方式实现
- 二叉树基本算法,递归非递归遍历以及求高度、宽度等
- 扩展二叉树 建立 以及 前序遍历 中序遍历 后序遍历 的非递归算法
- 二叉树的先序、中序以及后序遍历(递归与非递归方法)
- 二叉树的实现以及递归遍历的精确模拟
- java实现二叉树的构建以及3种遍历方法
- Java 二叉树的实现以及遍历
- 创建二叉树的两种方法以及三种遍历方法