【100题】第四十二题 二叉树的非递归遍历
来源:互联网 发布:如何淘宝小二介入 编辑:程序博客网 时间:2024/05/16 15:33
一,前序遍历非递归:
根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。
void preOrder2(node *root) //非递归前序遍历
{
stack<node*> s;
node *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;
}
}
cout<<endl;
}
二,中序遍历非递归
根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。因此其处理过程如下:
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束
void inOrder2(node *root) //非递归中序遍历
{
stack<node*> s;
node *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; //将当前访问的元素的右孩子入栈
}
}
}
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void postOrder3(node *root) //非递归后序遍历
{
stack<node*> s;
node *cur; //当前结点
node *pre=NULL; //前一次访问的结点
s.push(root);
while(!s.empty())
{
cur=s.top();
if((cur->lchild==NULL&&cur->rchild==NULL)||
(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre=cur;
}
else
{
if(cur->rchild!=NULL)
s.push(cur->rchild);
if(cur->lchild!=NULL)
s.push(cur->lchild);
}
}
}
综合程序附录
#include "stdio.h"#include "stdlib.h" #include "stack.h"int count;//统计叶子节点个数 struct node{int data;//二叉树的节点值node *lchild,*rchild;//左右孩子节点 };/*不知道为什么 创建的时候需要返回值才 创建有效*/node *createTree(){node *root;int data;printf("input data:");scanf("%d",&data);//printf("output data:%d\n",data);if(data==0) root=NULL; else/*根左右 前序建立二叉树*/ { root=(node*)malloc(sizeof(node)); root->data=data; root->lchild=createTree(); root->rchild=createTree(); }return root;} void preOrder(node *root){if(root==NULL) return;else//不是空{printf("%d\n",root->data);preOrder(root->lchild);preOrder(root->rchild); } }void inOrder(node *root){if(root==NULL) return;else//不是空{inOrder(root->lchild);printf("%d\n",root->data);inOrder(root->rchild); } }void postOrder(node *root){if(root==NULL) return;else//不是空{postOrder(root->lchild);postOrder(root->rchild);printf("%d\n",root->data); } }void CountLeaves(node *root){if(root==NULL) return;else//不是空{if(root->lchild==NULL&&root->rchild==NULL) count++;CountLeaves(root->lchild);CountLeaves(root->rchild); } } int deepLength(node *root){int deep1,deep2;if(root==NULL) return 0; else { deep1=deepLength(root->lchild); deep2=deepLength(root->rchild); if(deep1>deep2) return deep1+1;//这个地方一定是返回+1 else return deep2+1; }}void CountNodes(node *root){if(root==NULL) return;else//不是空{ count++;CountNodes(root->lchild);CountNodes(root->rchild); } } void exchange(node *root){if(root==NULL) return; else { exchange(root->lchild); exchange(root->rchild); node *temp=root->lchild; root->lchild=root->rchild; root->rchild=temp; }}void search(node *root,int x){if(root==NULL) return ; else { if(root->data==x) { count++; printf("has\n"); } search(root->lchild,x); search(root->rchild,x); }}void preOrder2(node *root) //非递归前序遍历 { stack<node*> s; node *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; } } cout<<endl; }void inOrder2(node *root) //非递归中序遍历{ stack<node*> s; node *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; } } }void postOrder3(node *root) //非递归后序遍历{ stack<node*> s; node *cur; //当前结点 node *pre=NULL; //前一次访问的结点 s.push(root); while(!s.empty()) { cur=s.top(); if((cur->lchild==NULL&&cur->rchild==NULL)|| (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))) { cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); pre=cur; } else { if(cur->rchild!=NULL) s.push(cur->rchild); if(cur->lchild!=NULL) s.push(cur->lchild); } } }/*一定要记住直接输入1 2 3 0 0 0 0 建立的是 左二叉树 平衡的应该是 1 2 0 0 3 0 0*/int main(){node *root;//=(node*)malloc(sizeof(node));//这里不要初始化了 因为建立的时候要初始化 printf(" Please select what you want do\n");printf("----------------------------------------------\n");printf(" 1.前序创建二叉树\n");printf(" 2.递归前序遍历二叉树\n");printf(" 3.递归中序遍历二叉树\n");printf(" 4.递归后序遍历二叉树\n");printf(" 5.求叶节点个数\n");printf(" 6.求树的高度\n");printf(" 7.求二叉树节点个数\n");printf(" 8.交换左右子树\n");printf(" 9.查找有无某个节点\n");printf(" 10.非递归前序遍历二叉树\n");printf(" 11.非递归前序遍历二叉树\n");printf(" 12.非递归前序遍历二叉树\n");printf(" 15.退出\n"); int i;while(true){scanf("%d",&i); switch(i) { case 1: root=createTree(); printf("create tree is finished please select what you want do next:\n");break; case 2:printf("Now outPut data in PreOrder:\n"); preOrder(root); printf("output is over please select again\n");break; case 3: printf("Now outPut data in inOrder:\n"); inOrder(root);printf("output is over please select again\n");break; case 4: printf("Now outPut data in postOrder:\n"); postOrder(root);printf("output is over please select again\n");break; case 5: count=0; CountLeaves(root); printf("The leaves's count is:%d\n",count);printf("output is over please select again\n");break;//叶子节点的个数 case 6: int deep=deepLength(root); printf("The tree's deepLength is:%d\n",deep);printf("output is over please select again\n");break; case 7: count=0; CountNodes(root); printf("The leaves's count is:%d\n",count);printf("output is over\n"); break;//求二叉树节点个数 case 8: exchange(root); break; case 9: printf("please input what you want search\n"); int x; scanf("%d",&x); count=0; search(root,x);if(count!=0) { printf("The tree has this root\n"); printf("output is over please select again\n"); } else { printf("The tree not has this root\n"); printf("output is over please select again\n"); } break; case 10:printf("Now outPut data in PreOrder:\n"); preOrder2(root); printf("output is over please select again\n");break; case 11:printf("Now outPut data in PreOrder:\n"); inOrder2(root); printf("output is over please select again\n");break; case 12:printf("Now outPut data in PreOrder:\n"); postOrder3(root); printf("output is over please select again\n");break; case 15: exit(0); break;//包含在stdlib.h当中 } } return 0;}
- 【100题】第四十二题 二叉树的非递归遍历
- 二叉搜索树的非递归前中后序遍历 【微软面试100题 第四十三题】
- 第四十三题(递归和非递归俩种方法实现二叉树的前序遍历)
- 【算法题】二叉树非递归遍历
- 微软面试100题系列---二叉树的遍历递归和非递归实现
- 二叉树的递归,非递归遍历
- 二叉树的递归+非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的遍历--递归+非递归
- 二叉树的递归、非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的先中后序遍历,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的创建,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的非递归遍历以及递归遍历
- 二叉树的非递归遍历&递归遍历
- 二叉树的递归遍历和非递归遍历
- 【100题】第四十一题 非降序链表的并集
- 【cocos2d-x】利用CCScrollView, 实现帮助界面
- request.getSession(true) and request.getSession(false)
- java基础_时间:2012/8/18 星期六 21:02
- Swing 菜单JMenu
- 【100题】第四十二题 二叉树的非递归遍历
- 随机数
- Linux操作快捷键
- NSArray,NSSet,NSEnumerator,NSDictionary及对应Mutable介绍
- VB中事件和方法的区别
- argc与argv
- 信道
- hdu——2028(water army)
- 【100题】第四十四题 腾讯面试三道题