二叉树的遍历

来源:互联网 发布:python line.split 编辑:程序博客网 时间:2024/05/16 03:15

二叉树的非递归遍历

#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");}


原创粉丝点击