二叉树的三种遍历的非递归实现

三种遍历的非递归实现:

//coder:LEE

//20120309
#include<iostream>
#include<cassert>
#include<stack>
using namespace std;
struct BiTreeNode
{
int value;
BiTreeNode *pLeft;
BiTreeNode *pRight;
};
void AddNode(BiTreeNode *&root,int data)
{
if(root==NULL)
{
root=new BiTreeNode();
root->pLeft=NULL;
root->pRight=NULL;
root->value=data;
}
else if(data<root->value)
AddNode(root->pLeft,data);
else
AddNode(root->pRight,data);

}

/*

后序遍历(非递归)
思想是: 
先找到最左边的叶子并把路上遇到的节点依次压栈,然后弹出栈顶的元素(该元素为最左边的叶子),并判
断(1)它有没有右节点;(2)右节点是否被访问过。如果没有右节点或者右节点已被访问过,则出栈,访
问该节点,并设置have_visited为该节点。否则转到右子树,为下次循环,压栈做准备。
*/
void PostOrderNoRec(BiTreeNode *root)
{
stack<BiTreeNode *> s;
BiTreeNode *have_visited=NULL;
BiTreeNode *p=root;
while (p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->pLeft;
}
p=s.top();
if (p->pRight==NULL||have_visited==p->pRight)
{
cout<<p->value<<" ";
s.pop();
have_visited=p;
p=NULL;
}
else
p=p->pRight;
}
}
void InOrderNoRec(BiTreeNode *root)//中序遍历(非递归)
{
stack<BiTreeNode *> s;
BiTreeNode *have_visited=NULL;
BiTreeNode *p=root;
while (p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->pLeft;
}
p=s.top();
cout<<p->value<<" ";
s.pop();
if (p->pRight!=NULL)
p=p->pRight;
else
p=NULL;
}
}
void PreOrderNoRec(BiTreeNode *root)//先序遍历(非递归)
{
stack<BiTreeNode *> s;
BiTreeNode *have_visited=NULL;
BiTreeNode *p=root;
while (p!=NULL||!s.empty())
{
if(p!=NULL)
{
cout<<p->value<<" ";
s.push(p);
p=p->pLeft;
}
else
{
p=s.top();
s.pop();
p=p->pRight;
}
}
}
int main()
{
BiTreeNode * root=NULL;
AddNode(root,11);
AddNode(root,8);
AddNode(root,9);
AddNode(root,10);
AddNode(root,5);
AddNode(root,2);
AddNode(root,1);
AddNode(root,6);
AddNode(root,7);
PreOrderNoRec(root);
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言非递归实现二叉树的层序遍历(也称为广度优先遍历)通常使用队列数据结构。以下是一个简单的步骤描述和示例代码: 1. 定义一个结构体来表示二叉树节点,包含值和左右子节点指针。 ```c typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; } TreeNode; ``` 2. 创建一个队列,并初始化根节点(如果存在)。 3. 将根节点(如果有的话)加入队列。 4. 当队列不为空时,执行以下操作: a. 弹出队首元素作为当前节点。 b. 访问当前节点(打印值或其他操作)。 c. 将当前节点的左子节点(如果存在)加入队列。 d. 将当前节点的右子节点(如果存在)加入队列。 5. 重复步骤4直到队列为空。 下面是对应的C语言代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <queue> void levelOrderTraversal(TreeNode* root) { if (root == NULL) return; // 如果根节点为空,直接返回 queue<TreeNode*> q; q.push(root); // 先将根节点入队 while (!q.empty()) { TreeNode* node = q.front(); q.pop(); // 弹出队首节点 printf("%d ", node->val); // 访问节点值 if (node->left != NULL) q.push(node->left); if (node->right != NULL) q.push(node->right); } } // 示例用法 int main() { // 构建一个简单的二叉树 TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode)); root->val = 1; root->left = (TreeNode*)malloc(sizeof(TreeNode)); root->left->val = 2; root->right = (TreeNode*)malloc(sizeof(TreeNode)); root->right->val = 3; root->left->left = (TreeNode*)malloc(sizeof(TreeNode)); root->left->left->val = 4; root->left->right = (TreeNode*)malloc(sizeof(TreeNode)); root->left->right->val = 5; levelOrderTraversal(root); printf("\n"); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值