二叉树的遍历
2012-10-25 10:14
309 查看
二叉树的非递归遍历
#include"stdio.h" #include<iostream> #include<stack> #include<queue> using namespace std; //数据结构 typedef struct node { int value; struct node *lchild; struct node *rchild; }BiNode; typedef BiNode* BiTree; typedef struct BTNode{ BiNode * btnode; bool isFrist; }BTNode; //初始化 void InitBiTree(BiTree *T) { *T = NULL; } //创建 void CreateBiTree(BiTree *T) { int value; printf("输入值:\n"); scanf("%d",&value); if(value!= 0) { *T = (BiNode *)malloc(sizeof(BiNode)); (*T)->value = value; (*T)->lchild = NULL; (*T)->rchild = NULL; CreateBiTree(&((*T)->lchild)); CreateBiTree(&((*T)->rchild)); } else { *T = NULL; return; } } //按层创建 void CreateBiTreeByLevel(BiTree *T,int *Array,int i,int len) { if((Array[i] == 0)|| i > len)return; *T = (BiNode *)malloc(sizeof(BiNode)); if(!(*T))exit(0); (*T) ->value = Array[i]; (*T)->lchild = NULL; (*T)->rchild = NULL; CreateBiTreeByLevel(&(*T)->lchild,Array,2*i,len); CreateBiTreeByLevel(&(*T)->rchild,Array,2*i+1,len); } void display(BiTree *t) //显示树形结构 { if(*t!=NULL) { cout<<(*t)->value; if((*t)->lchild!=NULL) { cout<<'('; display(&(*t)->lchild); } if((*t)->rchild!=NULL) { cout<<','; display(&(*t)->rchild); cout<<')'; } } } //----------------深度遍历二叉树-------递归的方法------- //前序遍历 void PreOrderTraverse(BiTree *t) { if(!(*t))return; printf("%d",(*t)->value); PreOrderTraverse(&((*t)->lchild)); PreOrderTraverse(&((*t)->rchild)); } // 后序遍历 void PostOrderTraverse(BiTree *t) { if(!(*t))return; PostOrderTraverse(&((*t)->lchild)); PostOrderTraverse(&((*t)->rchild)); printf("%d",(*t)->value); } //中序遍历 void InOrderTraverse(BiTree *t) { if(!(*t))return; InOrderTraverse(&(*t)->lchild); printf("%d",(*t)->value); InOrderTraverse(&(*t)->rchild); } //-------------------深度遍历二叉树---非递归方法--------------------------- //非递归前序遍历 /************************************************************************/ /* 1)访问节点p,将节点p入栈*/ /* 2)p左孩子不为空,则一直入栈,当p的左孩子为空时,出栈*/ /* 3)直到p为空或者栈s为空,遍历结束*/ /*前序遍历根左右,入栈时访问为谦虚,中序遍历时,左根右,出栈时访问*/ /************************************************************************/ void PreOrderTraverse1(BiTree *t) { stack <BiTree> s; BiNode *p = *t; while(p!=NULL||!s.empty()) { while(p) { printf("%d",p->value); s.push(p); p = p->lchild; } if(!s.empty()) { p = s.top(); s.pop(); p = p->rchild; } } } //非递归中序遍历 void InOrderTraverse1(BiTree *t) { stack<BiTree> s; BiNode *p = *t; while(p!=NULL || !s.empty()) { while(p) { s.push(p); p = p->lchild; } if(!s.empty()) { p = s.top(); printf("%d",p->value); s.pop(); p = p->rchild; } } } //后续非递归遍历 /* 第一种思路:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点, 此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同 的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。 这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现 在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。 */ void PostOrderTraverse1(BiTree *t) { stack<BTNode*> s; BiNode *p = *t; BTNode *temp; while(p!=NULL||!s.empty()) { while(p) { BTNode *btn = (BTNode *)malloc(sizeof(BTNode)); btn->btnode = p; btn->isFrist = true; s.push(btn); p = p->lchild; } if(!s.empty()) { temp = s.top(); s.pop(); if(temp->isFrist) { s.push(temp); temp->isFrist = false; p = temp->btnode->rchild; } else { printf("%d",temp->btnode->value); p = NULL; } } } } /* 第二种思路:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。 如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右 孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次 入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点 前面被访问。 */ void PostOrderTraverse2(BiTree *t) { stack<BiNode*> s; BiNode *pre = NULL; BiNode *cur = NULL; s.push(*t); while(!s.empty()) { cur = s.top(); if(((cur->lchild == NULL)&&(cur->rchild == NULL))||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))) { printf("%d",cur->value);//如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); //由于入栈时根右左,pre指向其右或者左节点, pre = cur; } else { if(cur->rchild!=NULL)s.push(cur->rchild); if(cur->lchild!=NULL)s.push(cur->lchild); } } } //---------------------按照层序遍历二叉树,二叉树的广度遍历--------------------- void LevelOrderTranverse(BiTree *t) { queue<BiNode *> q; BiNode * p = NULL; if(*t)q.push(*t); else return; while(!q.empty()) { p = q.front(); q.pop(); cout<<p->value<<"*"; if (p->lchild!=NULL)q.push(p->lchild); if (p->rchild!=NULL)q.push(p->rchild); } } int main() { BiTree T; InitBiTree(&T); int a[14] = {0,1,2,3,4,5,6,0,0,0,7,0,8,9};//从下标1开始,0标识没有节点 CreateBiTreeByLevel(&T,a,1,13); display(&T); /*printf("\n---------PreOrder---------------\n"); PreOrderTraverse(&T); printf("\n--------------------------------\n"); PreOrderTraverse1(&T); printf("\n---------InOrder-----------------\n"); InOrderTraverse(&T); printf("\n------------------------\n"); InOrderTraverse1(&T); printf("\n---------PostOrder---------------\n"); PostOrderTraverse(&T); printf("\n---------------------------------\n"); PostOrderTraverse1(&T); printf("\n---------------------------------\n"); PostOrderTraverse2(&T);*/ printf("\n------------lll---------------------\n"); LevelOrderTranverse(&T); system("pause"); }
相关文章推荐
- 二叉树 遍历
- 第十一周项目1(1)二叉树的层次遍历算法
- 二叉树的遍历算法(递归与非递归)
- 面试题23:二叉树层序遍历
- 二叉树的层次遍历
- 二叉树的前序,中序,后序遍历
- 【LeetCode】102. Binary Tree Level Order Traversal-二叉树水平顺序遍历
- 按层遍历二叉树
- 二叉树的遍历(25 分)
- python数据结构之二叉树的遍历实例
- 由前序遍历序列和中序遍历序列重建二叉树
- 二叉树的遍历
- 二叉树的构造与遍历(前序、中序、后序)
- 二叉树有先序遍历和中序遍历,构造出后序遍历
- [Java算法分析与设计]二叉树非递归实现遍历
- 二叉树的基本遍历方法
- Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
- 二叉树的基础应用(建树+叶子数+深度+遍历 )
- 算法导论 10.4.5 O(1)空间遍历二叉树
- 数据结构—树和二叉树-2.二叉树的层次遍历(BFS)