二叉树的非递归遍历
来源:互联网 发布:炒股软件官方下载 编辑:程序博客网 时间:2024/05/17 07:46
二叉树的非递归遍历
说明:非递归的三种遍历都要借助栈来实现。先序、中序写法类似也较易实现,后序稍难。
树结点结构:
struct BinTree{BinTree* lchild,*rchild;int val;}
一、先序遍历(树根->左子树->右子树)
思路:
1.从当前树根结点开始,一直向左走,挨个入栈并访问,走到尽头(为NULL的结点);
2.栈顶结点出栈,将p的右孩子赋给p(p=p->rchild),此时p为当前树根,重复1;
3.直到栈空。
代码如下:
void preOrder(BinTree *root){stack<BinTree *> s;BinTree *p = root;while (p || !s.empty()){while (p) // 1{printf("%d ", p->val);s.push(p);p = p->lchild;}if (!s.empty()) // 2{p = s.top();s.pop();p = p->rchild;}}}
二、中序遍历(左子树->树根->右子树)
思路:
1.从当前树根结点开始,一直向左走,挨个入栈(这里先不访问),走到尽头(为NULL的结点);
2.栈顶结点出栈并访问,将p的右孩子赋给p(p=p->rchild),此时p为当前树根,重复1;
3.直到栈空。
代码如下:
void inOrder(BinTree *root){stack<BinTree *> s;BinTree *p = root;while (p || !s.empty()){while (p) // 1{s.push(p);p = p->lchild;}if (!s.empty()) // 2{p = s.top();printf("%d ", p->val);s.pop();p = p->rchild;}}}
由前序遍历与中序遍历代码可以看出,中序遍历与前序遍历只是访问结点的时机不同,
前序遍历在结点入栈时访问,后序遍历在结点出栈时访问。
三、后序遍历(左子树->右子树->树根)
思路1:需要加入标志(创建另一种结点结构,加入isFirst标志),当结点第2次出现在栈顶时访问(这种方法与上面两种遍历代码也有许多相似之处,比较好记)。
1.从当前树根结点开始,一直向左走,挨个(转化成Node结点)入栈(这里先不访问)并标记为第1次出现,走到尽头(为NULL的结点);
2.栈顶结点p出栈,如果:
1)结点为第1次出现在栈顶(不包括入栈时),结点p(转化Node结点)再入栈并标记为第2次,此时p为当前树根,重复1;
2)结点为第2次出现在栈顶(不包括入栈时),访问该结点,重复2。
3.直到栈空。
struct Node{ BinTree *binTree; bool isFirst;};
代码如下:
void postOrder(BinTree *root){stack<Node *> s;BinTree *p = root;Node *tmp;while (p || !s.empty()){while (p) // 1{Node *node = (Node *)malloc(sizeof(Node));node->binTree = p;node->isFirst=true;s.push(node);p = p->lchild;}if (!s.empty()){tmp = s.top();s.pop();if (tmp->isFirst) // 2 1){tmp->isFirst = false;s.push(tmp);p = tmp->binTree->rchild;}else // 2 2){printf("%d ", tmp->binTree->val);p = NULL;}}}}
思路2:
1.根结点入栈;
2.取栈顶结点cur,判断:
1)cur无孩子结点,或其孩子结点已经被访问,则访问cur结点;
2)cur有孩子结点,cur的(如果有)右孩子入栈,再cur的(如果有)左孩子入栈(注意顺序)。
3.直到栈空。
代码如下:
void postOrder2(BinTree *root){stack<BinTree *> s;BinTree *cur;BinTree *pre = NULL;s.push(root); // 1while (!s.empty()){cur = s.top();if ((NULL == cur->lchild && NULL == cur->rchild) ||(NULL != pre && (pre == cur->lchild || pre == cur->rchild))) // 2 1){printf("%d ", cur->val);s.pop();}else // 2 2){if (cur->rchild) s.push(cur->rchild);if (cur->lchild) s.push(cur->lchild);}}}
- 二叉树的递归,非递归遍历
- 二叉树的递归+非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的遍历--递归+非递归
- 二叉树的递归、非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的先中后序遍历,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的创建,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的非递归遍历以及递归遍历
- 二叉树的非递归遍历&递归遍历
- 二叉树的递归遍历和非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历和非递归遍历
- 二叉树的构造,递归遍历,非递归遍历
- 二叉树的遍历(递归+非递归+层次遍历)
- 二叉树的递归遍历与非递归遍历
- PHP识别<?php?>但是不识别<??>
- PING通,无法打开网站
- OC-10.类的扩展
- 15000个英文单词Sec01.Part01 时间和方位
- commons-fileupload 核心API 分析
- 二叉树的非递归遍历
- virtual析构函数
- ceph rgw中的md_config_obs_t类
- Nginx rewrite配置规则
- 设计模式之责任链模式
- LibGDX_4.5: 演员组(Group)
- Swing多线程编程
- s5p4418-sdio接口的wifi模块驱动及往android层的延伸
- android之实现带图片和文本的Button