非递归实现前、中、后序历遍二叉树(Java实现)
来源:互联网 发布:python gui界面实例 编辑:程序博客网 时间:2024/05/01 23:28
package myTree;
/******************************************************************************/
class Node<E> { //结点类,实际上是链表结点类
public E data;
public Node<E> next; //链表结点的后继
Node(E data, Node<E> next) { //带参数的构造函数
this.data = data;
this.next = next;
}
Node(E data) {
this(data, null);
}
Node() {
this(null, null);
}
}
/******************************************************************************/
class MyStack<E> { //栈类,实际上是链栈类,栈的每一个空间都是上面的Node<E>类对象
public Node<E> top; //用了Node<E>作为栈的栈顶
MyStack() {
this.top = null;
}
public boolean isEmpty() { //判断栈是否为空
return this.top == null;
}
public boolean push(E element) { //进栈
if (element == null) {
return false;
}
this.top = new Node<E>(element, this.top); //将elements作为栈顶,并把当前栈顶作为后继
return true;
}
public E pop() { //出栈
if (!isEmpty()) { //若栈不为空
E temp = this.top.data;
this.top = this.top.next; //将栈顶的后继作为栈顶,即弹出栈顶
return temp;
}
return null;
}
}
/******************************************************************************/
class TreeNode<E> { //二叉树的结点类,即二叉链表的结点类
public E data;
public TreeNode<E> LChild, RChild; //左、右孩子
public boolean hasVisited = false; //这里多设一个结点是否被访问过的标志位,预定为false即未被访问
public TreeNode(E data, TreeNode<E> LChild, TreeNode<E> RChild) {
this.data = data; //带有结点值、左右孩子的结点构造函数
this.LChild = LChild;
this.RChild = RChild;
}
public TreeNode(E data) { //仅有结点值的结点构造函数,即叶子结点
this(data, null, null);
}
public boolean isLeaf() { //判断当前结点是否为叶子结点
return (this.LChild == null && this.RChild == null);
}
}
/******************************************************************************/
class MyTree<E> { //二叉树类
public TreeNode<E> root; //二叉树的根
private int leafCounts = 0; //叶子结点总数
//private int treeDeepth = 0; //好像树的深度还是需要在后序历遍里面用递归来实现
private int nodeCounts = 0; //统计节点总数
public MyTree(TreeNode<E> root) { //带有根结点的构造函数 public boolean isEmpty() { //判断是否为空二叉树 while (p != null || !myStack.isEmpty()) { //每次循环都把p当作一棵树,则p为不空的根且栈不空 if (p != null) { //若p不为空 if (p.isLeaf()) { //若当前结点为叶子,则leafCounts增加 while (p != null || !myStack.isEmpty()) { while (p != null || !myStack.isEmpty()) { /*public int getTreeDeepth(){ public int gerNodeCounts(){ /******************************************************************************/ public static MyTree<String> createTree() { //构造一颗预定的二叉树 public static void main(String[] args) { /** 该二叉树如下:按先序历遍的话该二叉树是: 好 好 学 习 , 天 天 向 上 @ #
public MyTree() { //构造函数将二叉树的根root初始化为null
root = null;
}
this.root = root;
// treeDeepth = 1;
nodeCounts = 1;
}
return this.root == null;
}
/*============================================================================*/
public void rootFirst() { //二叉树的非递归先序历遍
System.out.print("利用栈的非递归先序历遍:");
MyStack<TreeNode<E>> myStack = new MyStack<TreeNode<E>>(); //创建一个容纳二叉树类结点的栈
TreeNode<E> p = this.root; //p为根
System.out.print(p.data + " "); //访问结点,实际上只是打印结点的数据
myStack.push(p); //将当前节点进栈
leafCounts++;
}
p = p.LChild; //将p的左孩子赋给p作为新的树
} else { //若p为空但栈不空
p = myStack.pop(); //从栈中弹出栈顶元素赋给p
p = p.RChild; //将p的右孩子赋给p作为新的树
}
}
System.out.println();
}
/*============================================================================*/
public void rootSecond() { //二叉树的非递归先序历遍
System.out.print("利用栈的非递归中序历遍:");
MyStack<TreeNode<E>> myStack = new MyStack<TreeNode<E>>();
TreeNode<E> p = this.root;
if (p != null) {
myStack.push(p);
p = p.LChild;
} else { //实际上先序和中序的区别只在于打印结点数据的时机不同
p = myStack.pop();
System.out.print(p.data + " "); //访问结点数据
p = p.RChild;
}
}
System.out.println();
}
/*============================================================================*/
public void rootLast() {
System.out.print("利用栈的非递归后序历遍:");
MyStack<TreeNode<E>> myStack = new MyStack<TreeNode<E>>();
TreeNode<E> p = this.root;
if (p.LChild != null && !p.LChild.hasVisited) { //是否被访问过的标志位用在这里就OK了
myStack.push(p); //将当前结点进栈
//System.out.println(p.data + "进栈,进入左子树!");
p = p.LChild; //进入左子树
} else if (p.RChild != null && !p.RChild.hasVisited) { //是否被访问过的标志位用在这里就OK了
myStack.push(p);
//System.out.println(p.data + "进栈,进入右子树!");
p = p.RChild;
} else { //若当前结点无左、右子树(即叶子结点)或者其左、右孩子(也意味着子树)已被访问过
System.out.print( p.data+ " "); //访问该结点
p.hasVisited = true; //将当前结点设置为已访问,即true
p = myStack.pop(); //将栈顶弹出作为当前的根
//treeDeepth++;
nodeCounts++; //每个节点被访问一次,意味着有一个节点,故可统计节点数
}
}
System.out.println();
}
/*============================================================================*/
public int getLeafCounts() { //获得二叉树的叶子结点总数
return this.leafCounts;
}
return this.treeDeepth;
}*/
return this.nodeCounts;
}
}
public class TreeTest3 {
TreeNode<String> a, b, c, d, e, f, g;
a = new TreeNode<String>("上", new TreeNode<String>("@"), new TreeNode<String>("#"));
b = new TreeNode<String>("习", null, new TreeNode<String>("*"));
c = new TreeNode<String>("天", new TreeNode<String>("天"), null);
d = new TreeNode<String>("学", null, b);
e = new TreeNode<String>("向", a, null);
f = new TreeNode<String>("好", d, c);
g = new TreeNode<String>("好", f, e);
return new MyTree<String>(g);
}
MyTree<String> myTree = createTree();
myTree.rootFirst();
myTree.rootSecond();
myTree.rootLast();
System.out.println("该二叉树的叶子数为:" + myTree.getLeafCounts());
//System.out.println("该二叉树的总深度为:"+ myTree.getTreeDeepth());
System.out.println("该二叉树的节点数为:"+ myTree.gerNodeCounts());
}
}
/**
*
*
* 程序输出如下:
利用栈的非递归先序历遍:好 好 学 习 * 天 天 向 上 @ #
利用栈的非递归中序历遍:学 习 * 好 天 天 好 @ 上 # 向
利用栈的非递归后序历遍:* 习 学 天 天 好 @ # 上 向 好
该二叉树中的叶子数为: 4
*/
* 好
* 好 向
* 学 天 上
* 习 天 @ #
* *
*/
- 非递归实现前、中、后序历遍二叉树(Java实现)
- 二叉树的前序、中序、后序(递归、非递归)遍历java实现
- JAVA实现二叉树的前、中、后序遍历(递归与非递归)
- Java实现二叉树的前序、中序、后序遍历(非递归方法)
- 二叉树的前、中、后遍历递归和非递归java实现
- Java实现完全二叉树,实现非递归前序,中序,后序遍历
- 二叉树非递归前、中、后序遍历实现
- 二叉树的前序、中序、后序的实现(递归和非递归)
- 【LintCode-66】二叉树的前序遍历(Java实现-递归算法/非递归算法)
- 用java实现二叉树非递归的前序,中序,后序遍历算法
- 二叉树的非递归前序,中序,后序遍历的Java实现
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- java 实现二叉树【递归/非递归】
- 非递归实现二叉树的遍历(前序、中序、后序)
- C++实现二叉树的非递归遍历(层,前,中,后序)
- 【数据结构基础】前序、中序、后序线索化二叉树(非递归实现)
- java语言实现二叉树的前序、中序与后序遍历(递归与非递归)
- java语言实现二叉树的前序、中序与后序遍历(递归与非递归) 层次遍历
- ExtJs学习笔记01
- pc机取得并修改arm linux IP地址 网关 子网掩码 主机名等信息
- ARM7在嵌入式应用中启动程序的实现
- 各种经典排序算法的实现(待完善)
- 图的广度历遍算法(待完善)
- 非递归实现前、中、后序历遍二叉树(Java实现)
- 中国现代教育个人体会
- 2010,新的一年。
- 祝大家新年快乐
- 坤哥走了
- 浅谈整数(一)|强推
- ruby与rt实现上标英文和拼音功能
- 《冒号论坛》开张
- 微软2010年要做10件大事:弃IE9购Facebook