导航:首页 > 编程语言 > 二叉树遍历非递归java

二叉树遍历非递归java

发布时间:2022-08-17 04:19:36

1. 二叉树后序遍历非递归算法

#include
<stdio.h>
#include
<stdlib.h>
struct
tree
{
char
data;
struct
tree
*lchild;
struct
tree
*rchild;
};
typedef
struct
tree
*
treptr;
treptr
build(treptr
t)//先序建树
{
char
c;
c=getchar();
if(c=='#')
{
t=NULL;
}
else
{
t=(treptr)malloc(sizeof(struct
tree));
t->data=c;
t->lchild=build(t->lchild);
t->rchild=build(t->rchild);
}
return
t;
}
void
postdorder(treptr
root)//这是递归实现
{
if
(root!=NULL)
{
postdorder(root->lchild);
postdorder(root->rchild);
printf("%c",root->data);
}
}
struct
stack
{
treptr
*top,*base;
};
typedef
struct
stack
*stackptr;
void
init
(stackptr
s)//初始化栈
{
s->base=(treptr*)malloc(sizeof(treptr)*100);
s->top=s->base;
}
void
push(stackptr
s,treptr
t)//入栈
{
*(s->top++)=t;
}
treptr
pop(stackptr
s)//弹出栈顶元素
{
treptr
t;
t=*(--(s->top));
return
t;
}
treptr
gettop(stackptr
s)//取栈顶元素
{
treptr
*l=s->top-1;
return
*(l);
}
void
postorder(treptr
t)//这是非递归后序实现
{
stackptr
s=(stackptr)malloc(sizeof(struct
stack));
treptr
temp=t;
treptr
p;
treptr
lastvist=NULL;
init(s);
p=t;
while(p||s->top!=s->base)
{
while(p)
{
push(s,p);
p=p->lchild;
}
temp=gettop(s);
if(temp->rchild==NULL||temp->rchild==lastvist)
{
putchar(temp->data);
lastvist=pop(s);
}
else
p=temp->rchild;
}
}
int
main()
{
treptr
t=NULL;
t=build(t);
postdorder(t);
printf("非递归后序遍历\
");
postorder(t);
printf("\
");
return
0;
}
程序如上,可以运行。
我空间中有中序遍历的非递归实现。
不过给你写的是后序遍历的递归实现和非递归实现,它两个输出的结果是一致的。
输入
234##5#6##7##回车
就可以看到结果。
中序遍历及其对应树可以参考我空间中的文章
http://hi..com/huifeng00/blog/item/2ca470f56694f62e730eec39.html

2. 用java编写一个非递归的二叉树的遍历,急要!!!

import java.util.LinkedList;
import java.util.Stack;

public class MainTest {

public static void scanTree1(Tree root) { //横向遍历
LinkedList<Tree> queue = new LinkedList<Tree>();
queue.add(root);
while (!queue.isEmpty()) {
Tree node = queue.poll();
System.out.println(node.getData());
Tree left = node.getLeft();
Tree right = node.getRight();
if (left != null) {
queue.add(left);
}
if (right != null) {
queue.add(right);
}
}
}

public static void scanTree2(Tree root) { //纵向前序
Tree node = root;
Stack<Boolean> stack = new Stack<Boolean>();
boolean leftFlg = false;
while (true) {
System.out.println(node.getData());
if (node.getLeft() != null && leftFlg) {
node = node.getLeft();
stack.add(true);
leftFlg = true;
} else if (node.getRight() != null) {
node = node.getRight();
stack.add(false);
leftFlg = true;
} else if (stack.isEmpty()) {
break;
} else if (stack.pop()) {
node = node.getParent();
leftFlg = false;
}
}
}

public static void scanTree3(Tree root) {//纵向中序
Tree node = root;
Stack<Boolean> stack = new Stack<Boolean>();
boolean leftFlg = false;
while (true) {
if (node.getLeft() != null && leftFlg) {
node = node.getLeft();
stack.add(true);
leftFlg = true;
} else if (node.getRight() != null) {
System.out.println(node.getData());
node = node.getRight();
stack.add(false);
leftFlg = true;
} else if (stack.isEmpty()) {
break;
} else if (stack.pop()) {
node = node.getParent();
leftFlg = false;
}
}
}

public static void scanTree4(Tree root) {//纵向后序
Tree node = root;
Stack<Boolean> stack = new Stack<Boolean>();
boolean leftFlg = false;
while (true) {
if (node.getLeft() != null && leftFlg) {
node = node.getLeft();
stack.add(true);
leftFlg = true;
} else if (node.getRight() != null) {
node = node.getRight();
stack.add(false);
leftFlg = true;
} else if (stack.isEmpty()) {
break;
} else if (stack.pop()) {
System.out.println(node.getData());
node = node.getParent();
leftFlg = false;
}
}
}

public static void main(String[] args) {
Tree root = new Tree();
// TODO
scanTree1(root);
scanTree2(root);
scanTree3(root);
scanTree4(root);
}
}

class Tree {
private Tree left;
private Tree right;
private Tree parent;
private Object data;

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}

public Tree getLeft() {
return left;
}

public void setLeft(Tree left) {
this.left = left;
}

public Tree getRight() {
return right;
}

public void setRight(Tree right) {
this.right = right;
}

public Tree getParent() {
return parent;
}

public void setParent(Tree parent) {
this.parent = parent;
}
}

3. java 用递归创建二叉树,非递归遍历二叉树输出节点

我自己用递归写了下,不知道能不能给你帮助:

测试类:
package tree;

import java.util.*;

public class Test {

public static void main(String[] args){
List<Tree> trees=new ArrayList<Tree>();
int id=1;
Tree tree1=new Tree(0,id++,"张三丰");
Tree tree2=new Tree(tree1.getId(),id++,"武当宋大侠宋远桥");
Tree tree3=new Tree(tree1.getId(),id++,"武当俞二侠俞莲舟");
Tree tree4=new Tree(tree1.getId(),id++,"武当俞三侠俞岱岩");
Tree tree5=new Tree(tree1.getId(),id++,"武当张四侠张松溪");
Tree tree6=new Tree(tree1.getId(),id++,"武当张五侠张翠山");
Tree tree7=new Tree(tree1.getId(),id++,"武当殷六侠殷梨亭");
Tree tree8=new Tree(tree1.getId(),id++,"武当莫七侠莫声谷");
Tree tree9=new Tree(tree6.getId(),id++,"明教张无忌");
Tree tree13=new Tree(tree2.getId(),id++,"叛徒宋青书");

Tree tree10=new Tree(0,id++,"任我行");
Tree tree11=new Tree(tree10.getId(),id++,"令狐冲");
Tree tree12=new Tree(tree10.getId(),id++,"任盈盈");

trees.add(tree1);
trees.add(tree2);
trees.add(tree3);
trees.add(tree4);
trees.add(tree5);
trees.add(tree6);
trees.add(tree7);
trees.add(tree8);
trees.add(tree9);
trees.add(tree10);
trees.add(tree11);
trees.add(tree12);
trees.add(tree13);

for(int i=0;i<trees.size();i++){
Tree tree=trees.get(i);
if(tree.getParentId()==0){
tree.showChildTree(trees);
}
}

}

}

树类:
package tree;

import java.util.List;

public class Tree {
private int parentId;
private int id;
private String showStr;
private String Spaces="";

public Tree() {
// TODO Auto-generated constructor stub
}
public Tree(int parentId,int id,String showStr){
this.parentId=parentId;
this.id=id;
this.showStr=showStr;
}

public void showChildTree(List<Tree> trees){
if(parentId!=0){
trees.get(id-1).setSpaces(trees.get(parentId-1).getSpaces()+" ");
}
System.out.println(trees.get(id-1).getSpaces()+showStr);
for(int i=0;i<trees.size();i++){
Tree tree=trees.get(i);
if(tree.getParentId()==id){
tree.showChildTree(trees);
}
}

}

public int getParentId() {
return parentId;
}

public void setParentId(int parentId) {
this.parentId = parentId;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getShowStr() {
return showStr;
}

public void setShowStr(String showStr) {
this.showStr = showStr;
}

public String getSpaces() {
return Spaces;
}

public void setSpaces(String spaces) {
Spaces = spaces;
}

}

效果图:
张三丰
武当宋大侠宋远桥
叛徒宋青书
武当俞二侠俞莲舟
武当俞三侠俞岱岩
武当张四侠张松溪
武当张五侠张翠山
明教张无忌
武当殷六侠殷梨亭
武当莫七侠莫声谷
任我行
令狐冲
任盈盈

4. 用JAVA语言实现二叉树的层次遍历的非递归算法及查找算法。

先序非递归算法
【思路】
假设:T是要遍历树的根指针,若T != NULL
对于非递归算法,引入栈模拟递归工作栈,初始时栈为空。
问题:如何用栈来保存信息,使得在先序遍历过左子树后,能利用栈顶信息获取T的右子树的根指针?
方法1:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
方法2:访问T->data后,将T->rchild入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T->rchild,出栈,遍历以该指针为根的子树。
【算法1】
void PreOrder(BiTree T, Status ( *Visit ) (ElemType e))

{ // 基于方法一
InitStack(S);
while ( T!=NULL || !StackEmpty(S)){
while ( T != NULL ){
Visit(T->data) ;
Push(S,T);
T = T->lchild;
}
if( !StackEmpty(S) ){
Pop(S,T);
T = T->rchild;
}
}
}
【算法2】
void PreOrder(BiTree T, Status ( *Visit ) (ElemType e))

{ // 基于方法二
InitStack(S);
while ( T!=NULL || !StackEmpty(S) ){
while ( T != NULL ){
Visit(T->data);
Push(S, T->rchild);
T = T->lchild;
}
if ( !StackEmpty(S) ){
Pop(S,T);
}
}
}
进一步考虑:对于处理流程中的循环体的直到型、当型+直到型的实现。

中序非递归算法
【思路】
T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
问题:如何用栈来保存信息,使得在中序遍历过左子树后,能利用栈顶信息获取T指针?
方法:先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
【算法】
void InOrder(BiTree T, Status ( *Visit ) (ElemType e))
{
InitStack(S);
while ( T!=NULL || !StackEmpty(S) ){
while ( T != NULL ){
Push(S,T);
T = T->lchild;
}
if( !StackEmpty(S) ){
Pop(S, T);
Visit(T->data);
T = T->rchild;
}
}
}
进一步考虑:对于处理流程中的循环体的直到型、当型+直到型的实现。

后序非递归算法
【思路】
T是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。
可采用标记法,结点入栈时,配一个标志tag一同入栈(0:遍历左子树前的现场保护,1:遍历右子树前的现场保护)。
首先将T和tag(为0)入栈,遍历左子树;返回后,修改栈顶tag为1,遍历右子树;最后访问根结点。 [Page]
typedef struct stackElement{
Bitree data;
char tag;
}stackElemType;
【算法】
void PostOrder(BiTree T, Status ( *Visit ) (ElemType e))
{
InitStack(S);
while ( T!=NULL || !StackEmpty(S) ){
while ( T != NULL ){
Push(S,T,0);
T = T->lchild;
}
while ( !StackEmpty(S) && GetTopTag(S)==1){
Pop(S, T);
Visit(T->data);
}
if ( !StackEmpty(S) ){
SetTopTag(S, 1); // 设置栈顶标记
T = GetTopPointer(S); // 取栈顶保存的指针
T = T->rchild;
}else break;
}
}

5. 二叉树的后序遍历,非递归

后序遍历的非递归步骤类似于中序遍历,在遍历左子树前将根结点指针送入栈中
但是左子树遍历完成后,无法访问根结点,只有在右子树遍历完后,才能访问根结点

如果不使用标志位区分第几次到达根结点,可以利用如下的后序遍历特征来完成:
当栈顶元素(根)的右子树为空(即:无右孩子),或者是右子树非空但是已遍历完,即右孩子恰好是刚才访问过的结点,此时应访问栈顶结点,并在访问后退栈
否则,如果栈顶元素的右孩子非空且未遍历,此时直接访问栈顶元素的右孩子而不退栈

算法要点只是需要记住最近访问过的结点即可,也就是每次访问一个结点后,就记住这个结点

6. 二叉树中序遍历的非递归算法

#define MAXNODE 100 //二叉树最大节点数
//定义二叉树链式结构
typedef struct BitNode
{
char data; //数据域
struct BitNode *lchild,*rchild;//左右指针域
}BitNode,*BiTree;
//二叉树进行中序非递归遍历
void NRInorder(BiTree t)
{
BiTree s; //s-指向当前节点
BiTree stack[MAXNODE]; //定义栈
int top=-1; //初始化栈顶指针

if(t==NULL)
return;

stack[++top]=t;//根指针入栈
s=t->lchild; //s指向左子树
while(s!=NULL||top!=-1)//当存在节点(涉及到根下右子树)或者栈不为空,进行遍历
{
while(s!=NULL) //如果存在节点,寻找最左子树并入栈
{
if(top>=MAXNODE-1)
{
printf("栈为满\n");
return;
}
stack[++top]=s;//当前节点入栈
s=s->lchild; //左子树进行遍历
}

if(top==-1)
{
printf("栈为空\n");
return;
}

s=stack[top--]; //弹出栈顶元素到s中
printf("%c ",s->data); //输出当前节点元素值
s=s->rchild; //遍历右子树

}

}

7. 二叉树中序非递归遍历算法

#define MAXNODE 100 //二叉树最大节点数
//定义二叉树链式结构
typedef struct BitNode
{
char data; //数据域
struct BitNode *lchild,*rchild;//左右指针域
}BitNode,*BiTree;
//二叉树进行中序非递归遍历
void NRInorder(BiTree t)
{
BiTree s; //s-指向当前节点
BiTree stack[MAXNODE]; //定义栈
int top=-1; //初始化栈顶指针

if(t==NULL)
return;

stack[++top]=t;//根指针入栈
s=t->lchild; //s指向左子树
while(s!=NULL||top!=-1)//当存在节点(涉及到根下右子树)或者栈不为空,进行遍历
{
while(s!=NULL) //如果存在节点,寻找最左子树并入栈
{
if(top>=MAXNODE-1)
{
printf("栈为满\n");
return;
}
stack[++top]=s;//当前节点入栈
s=s->lchild; //左子树进行遍历
}
if(top==-1)
{
printf("栈为空\n");
return;
}
s=stack[top--]; //弹出栈顶元素到s中
printf("%c ",s->data); //输出当前节点元素值
s=s->rchild; //遍历右子树

}

}

8. 怎样实现二叉树的前序遍历的非递归算法

在前面一文,说过二叉树的递归遍历算法(二叉树先根(先序)遍历的改进),此文主要讲二叉树的非递归算法,采用栈结构
总结先根遍历得到的非递归算法思想如下:
1)入栈,主要是先头结点入栈,然后visit此结点
2)while,循环遍历当前结点,直至左孩子没有结点
3)if结点的右孩子为真,转入1)继续遍历,否则退出当前结点转入父母结点遍历转入1)
先看符合此思想的算法:
[cpp]
view
plain

print?
int
(const
BiTree
&T,
int
(*VisitNode)(TElemType
data))
{
if
(T
==
NULL)
{
return
-1;
}
BiTNode
*pBiNode
=
T;
SqStack
S;
InitStack(&S);
Push(&S,
(SElemType)T);
while
(!IsStackEmpty(S))
{
while
(pBiNode)
{
VisitNode(pBiNode->data);
if
(pBiNode
!=
T)
{
Push(&S,
(SElemType)pBiNode);
}
pBiNode
=
pBiNode->lchild;
}
if(pBiNode
==
NULL)
{
Pop(&S,
(SElemType*)&pBiNode);
}
if
(
pBiNode->rchild
==
NULL)
{
Pop(&S,
(SElemType*)&pBiNode);
//如果此时栈已空,就有问题
}
pBiNode
=
pBiNode->rchild;
}
return
0;
}

9. 如何编程实现二叉树的非递归遍历

前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。
1.递归实现

void preOrder1(BinTree *root) //递归前序遍历
{
if(root!=NULL)
{
cout<<root->data<<" ";
preOrder1(root->lchild);
preOrder1(root->rchild);
}
}

2.非递归实现
根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。

void preOrder2(BinTree *root) //非递归前序遍历
{
stack<BinTree*> s;
BinTree *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;
}
}
}

二.中序遍历
中序遍历按照“左孩子-根结点-右孩子”的顺序进行访问。
1.递归实现

void inOrder1(BinTree *root) //递归中序遍历
{
if(root!=NULL)
{
inOrder1(root->lchild);
cout<<root->data<<" ";
inOrder1(root->rchild);
}
}

2.非递归实现
根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。因此其处理过程如下:
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束

void inOrder2(BinTree *root) //非递归中序遍历
{
stack<BinTree*> s;
BinTree *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
cout<<p->data<<" ";
s.pop();
p=p->rchild;
}
}
}

10. 二叉树的非递归遍历

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<math.h>
typedef struct BiTNode
{
int data;
BiTNode *lchild,*rchild; // 左右孩子指针
}BiTNode,*BiTree;
void visit(int e)
{
printf("->%d",e);
}
void InitBiTree(BiTree &T)// 操作结果:构造空二叉树T
{
T=NULL;
}
void CreateBiTree(BiTree &T)
//按先序次序输入二叉树中结点的值,构造二叉链表表示的二叉树T。变量Nil表示空(子)树。
{
int number;
scanf("%d",&number); // 输入结点的值
if(number==0) // 结点的值为空
T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiTNode)); // 生成根结点
if(!T)
exit(OVERFLOW);
T->data=number; // 将值赋给T所指结点
CreateBiTree(T->lchild); // 递归构造左子树
CreateBiTree(T->rchild); // 递归构造右子树
}
}

void DestroyBiTree(BiTree &T)// 初始条件:二叉树T存在。操作结果:销毁二叉树T
{
if(T) // 非空树
{
DestroyBiTree(T->lchild); // 递归销毁左子树,如无左子树,则不执行任何操作
DestroyBiTree(T->rchild); // 递归销毁右子树,如无右子树,则不执行任何操作
free(T); // 释放根结点
T=NULL; // 空指针赋0
}
}

void PreOrderTraverse(BiTree T,void(*Visit)(int))
//二叉树T存在,Visit是对结点操作的应用函数,先序递归遍历T,对每个结点调用函数Visit一次且仅一次
{
if(T) //T不为空时遍历
{
Visit(T->data); // 先访问根结点
PreOrderTraverse(T->lchild,Visit); // 再先序遍历左子树
PreOrderTraverse(T->rchild,Visit); // 最后先序遍历右子树
}
}

void InOrderTraverse(BiTree T,void(*Visit)(int))
//二叉树T存在,Visit是对结点操作的应用函数,中序递归遍历T,对每个结点调用函数Visit一次且仅一次
{
if(T)
{ InOrderTraverse(T->lchild,Visit); // 先中序遍历左子树
Visit(T->data); // 再访问根结点
InOrderTraverse(T->rchild,Visit); // 最后中序遍历右子树
}
}

void PostOrderTraverse(BiTree T,void(*Visit)(int))
// 二叉树T存在,Visit是对结点操作的应用函数,后序递归遍历T,对每个结点调用函数Visit一次且仅一次
{
if(T) // T不空
{ PostOrderTraverse(T->lchild,Visit); // 先后序遍历左子树
PostOrderTraverse(T->rchild,Visit); // 再后序遍历右子树
Visit(T->data); // 最后访问根结点
}
}

void main()
{
char m;
BiTree T;
InitBiTree(T); // 初始化二叉树T
do{
printf("\n");
printf("##################二叉树的基本操作###########################\n");
printf("×××××××××1.二叉树的创建××××××××××××××\n");
printf("×××××××××2.先序递归遍历二叉树×××××××××××\n");
printf("×××××××××3.中序递归遍历二叉树×××××××××××\n");
printf("×××××××××4.后序递归遍历二叉树×××××××××××\n");
printf("×××××××××5.退出程序××××××××××××××××\n");
printf("#############################################################\n");
printf("请输入你的选择:");
scanf("%c",&m);
switch(m) {
case '1':
printf("按先序次序输入二叉树中结点的值,输入0表示节点为空,如:(1 2 3 0 0 4 5 0 6 0 0 7 0 0 0)\n");
printf("\n请按先序次序输入二叉树中结点的值:");
CreateBiTree(T); // 建立二叉树T
break;
case '2':
printf("先序递归遍历二叉树: ");
PreOrderTraverse(T,visit); // 先序递归遍历二叉树T
break;
case '3':
printf("\n中序递归遍历二叉树: ");
InOrderTraverse(T,visit); // 中序递归遍历二叉树T
break;
case '4':
printf(" \n后序递归遍历二叉树:");
PostOrderTraverse(T,visit); // 后序递归遍历二叉树T
break;
case '5':break;
default:
printf("输入的字符不对,请重新输入!");
break;

}
getchar();
}while(m!='5');

}

阅读全文

与二叉树遍历非递归java相关的资料

热点内容
移动加密软件去哪下载 浏览:280
php弹出alert 浏览:207
吉林文档课件加密费用 浏览:131
传感器pdf下载 浏览:284
随车拍app绑定什么设备 浏览:895
方维团购系统源码 浏览:991
linux反弹shell 浏览:156
打印机接口加密狗还能用吗 浏览:299
二板股票源码 浏览:446
度人经pdf 浏览:902
怎么配置android远程服务器地址 浏览:960
java程序员看哪些书 浏览:943
什么app可以免费和外国人聊天 浏览:797
pdf手写笔 浏览:182
别永远伤在童年pdf 浏览:990
爱上北斗星男友在哪个app上看 浏览:421
主力散户派发源码 浏览:671
linux如何修复服务器时间 浏览:61
荣县优途网约车app叫什么 浏览:479
百姓网app截图是什么意思 浏览:229