二叉树后序遍历的迭代实现

来源:互联网 发布:c51单片机 编辑:程序博客网 时间:2024/06/05 18:56
#include <stdio.h>#include <stdlib.h>struct BinTreeNode{    int Element;    int visited;//用于标记当前节点有没有被访问过    struct BinTreeNode* Left;    struct BinTreeNode* Right;};//以下代码用于建树,便于测试中序遍历程序是否正确struct BinTreeNode* CreateNode(int data){//创造新节点    struct BinTreeNode* temp;    temp=(struct BinTreeNode*)malloc(sizeof(struct BinTreeNode));    if(temp!=NULL){        temp->Element=data;        temp->visited=0;        temp->Left=NULL;        temp->Right=NULL;    }    return temp;}struct BinTreeNode* FindNode(struct BinTreeNode* BinTree,int data)//查找{    if(BinTree==NULL)        return NULL;    if(BinTree->Element==data)        return BinTree;    struct BinTreeNode* temp=NULL;    if(BinTree->Left!=NULL)        temp=FindNode(BinTree->Left,data);    if(temp==NULL&&BinTree->Right!=NULL)        temp=FindNode(BinTree->Right,data);    return temp;}//假设每个节点值不同#define LEFT 1#define RIGHT 0struct BinTreeNode* InsertNode(struct BinTreeNode* BinTree,int loc,int dir,int data)//插入节点,loc代表插入的数的父节点的值,dir表示方向{    struct BinTreeNode* parent=FindNode(BinTree,loc);    if(parent!=NULL){        struct BinTreeNode* temp=CreateNode(data);        if(dir==LEFT)            parent->Left=temp;        else            parent->Right=temp;    }    return BinTree;}//二叉树前序遍历的迭代实现,用到栈/*思路:后序不同于前序和中序,后序要访问完左子树和右子树才能访问节点;因此遍历到一个节点,访不访问他取决于它的左右子树是不是均被访问过了;需要在结构体中加入一个用来判断的变量visited,如果其左右子树均被访问过,就赋值为1过程:当前节点,沿它的左路径,开始遍历,直到路径末尾,开始回溯回溯过程中的节点的左儿子一定被访问过了或者不存在,如果其右儿子不存在或者右儿子已经被访问过,访问当前节点如果其右儿子存在,此时以其右儿子为基础,再去遍历其左路径*/void PostOrderTrversal(struct BinTreeNode* BinTree){    //建栈    struct BinTreeNode* stack[100];    int top=-1;    int flag;//判断要不要去遍历一个新的 (子)树左路径    struct BinTreeNode* Temp=BinTree;    while(Temp!=NULL||top>=0){        flag=1;        while(Temp!=NULL){//遍历 (子)树左路径            Temp->visited=1;            top++;            stack[top]=Temp;            Temp=Temp->Left;        }        while(flag&&top>=0){           if(stack[top]->Right==NULL||stack[top]->Right->visited==1){//右儿子不存在或者右儿子已经被访问过              printf("%d ",stack[top]->Element);              top--;           }           else{              Temp=stack[top]->Right;              flag=0;//flag为0,遍历一个新的 (子)树左路径           }        }    }    return;}int main(){    struct BinTreeNode* BinTree;    //先手工创建一个树  //不提倡此类建树方法,只是暂时用于测试程序    BinTree=CreateNode(10);    BinTree=InsertNode(BinTree,10,1,20);    BinTree=InsertNode(BinTree,10,0,30);    BinTree=InsertNode(BinTree,30,1,40);    BinTree=InsertNode(BinTree,40,0,50);    //遍历    PostOrderTrversal(BinTree);    return 0;}
//不用flag也可以
#include <stdio.h>#include <stdlib.h>struct BinTreeNode{    int Element;    int visited;//用于标记当前节点有没有被访问过    struct BinTreeNode* Left;    struct BinTreeNode* Right;};//以下代码用于建树,便于测试中序遍历程序是否正确struct BinTreeNode* CreateNode(int data){//创造新节点    struct BinTreeNode* temp;    temp=(struct BinTreeNode*)malloc(sizeof(struct BinTreeNode));    if(temp!=NULL){        temp->Element=data;        temp->visited=0;        temp->Left=NULL;        temp->Right=NULL;    }    return temp;}struct BinTreeNode* FindNode(struct BinTreeNode* BinTree,int data)//查找{    if(BinTree==NULL)        return NULL;    if(BinTree->Element==data)        return BinTree;    struct BinTreeNode* temp=NULL;    if(BinTree->Left!=NULL)        temp=FindNode(BinTree->Left,data);    if(temp==NULL&&BinTree->Right!=NULL)        temp=FindNode(BinTree->Right,data);    return temp;}//假设每个节点值不同#define LEFT 1#define RIGHT 0struct BinTreeNode* InsertNode(struct BinTreeNode* BinTree,int loc,int dir,int data)//插入节点,loc代表插入的数的父节点的值,dir表示方向{    struct BinTreeNode* parent=FindNode(BinTree,loc);    if(parent!=NULL){        struct BinTreeNode* temp=CreateNode(data);        if(dir==LEFT)            parent->Left=temp;        else            parent->Right=temp;    }    return BinTree;}//二叉树前序遍历的迭代实现,用到栈/*思路:后序不同于前序和中序,后序要访问完左子树和右子树才能访问节点;因此遍历到一个节点,访不访问他取决于它的左右子树是不是均被访问过了;需要在结构体中加入一个用来判断的变量visited,如果其左右子树均被访问过,就赋值为1过程:当前节点,沿它的左路径,开始遍历,直到路径末尾,开始回溯回溯过程中的节点的左儿子一定被访问过了或者不存在,如果其右儿子不存在或者右儿子已经被访问过,访问当前节点如果其右儿子存在,此时以其右儿子为基础,再去遍历其左路径*/void PostOrderTrversal(struct BinTreeNode* BinTree){    //建栈    struct BinTreeNode* stack[100];    int top=-1;    struct BinTreeNode* Temp=BinTree;    while(Temp!=NULL||top>=0){        while(Temp!=NULL){//遍历 (子)树左路径            Temp->visited=1;            top++;            stack[top]=Temp;            Temp=Temp->Left;        }        if(top>=0){           if(stack[top]->Right==NULL||stack[top]->Right->visited==1){//右儿子不存在或者右儿子已经被访问过              printf("%d ",stack[top]->Element);              top--;           }           else              Temp=stack[top]->Right;        }    }    return;}int main(){    struct BinTreeNode* BinTree;    //先手工创建一个树  //不提倡此类建树方法,只是暂时用于测试程序    BinTree=CreateNode(10);    BinTree=InsertNode(BinTree,10,1,20);    BinTree=InsertNode(BinTree,10,0,30);    BinTree=InsertNode(BinTree,30,1,40);    BinTree=InsertNode(BinTree,40,0,50);    //遍历    PostOrderTrversal(BinTree);    return 0;}


1 0
原创粉丝点击