二叉树非递归遍历

来源:互联网 发布:java判断上午下午 编辑:程序博客网 时间:2024/04/29 02:40

题记

二叉树的递归遍历比较简单,这里就不说了。二叉树非递归的实现要依赖栈,其中,后序遍历的非递归实现稍微复杂些。这里总结下,便于理解。

好了,不多说了,直接上代码,思路都在注释里。

代码部分:

#include<stdio.h>#include<stdlib.h>#define MAXSIZE 30typedef struct BSTreeNode{int m_value;struct BSTreeNode *m_pLeft;struct BSTreeNode *m_pRight;}BSTreeNode;//先得写个简单的int栈typedef struct stack{BSTreeNode* data[MAXSIZE];int top;}Stack;//-------- 栈的各种操作--------------------//int isEmpty(Stack *s){if(s->top == 0){return 1;}else{return 0;}}int push(Stack *s, BSTreeNode *node){if(s->top>=MAXSIZE){printf("error:栈已满\n");return -1;}s->data[s->top++] = node;return 1;}BSTreeNode * pop(Stack *s){if(s->top == 0){printf("error:栈内没有元素\n");return NULL;}return s->data[--(s->top)];}//------- 树的各种操作 --------------------------////生成二叉查找树BSTreeNode *insert(BSTreeNode *tree,BSTreeNode *n){if(tree == NULL){tree = n;}else if(n->m_value < tree->m_value){tree->m_pLeft = insert(tree->m_pLeft,n);}else{tree->m_pRight = insert(tree->m_pRight,n);}return tree;}//生成测试的二叉查找树BSTreeNode * create(){int data[]={10,6,14,4,8,12,16};int i;BSTreeNode * tree=NULL;for(i=0;i<sizeof(data)/sizeof(int);i++){BSTreeNode *fresh = (BSTreeNode*)malloc(sizeof(BSTreeNode));fresh->m_value = data[i];fresh->m_pLeft = fresh->m_pRight = NULL;tree = insert(tree,fresh);}return tree;}void destroy(BSTreeNode *cnode){if(cnode!=NULL){destroy(cnode->m_pLeft);destroy(cnode->m_pRight);free(cnode);}}//Description:非递归前序遍历//Algorithm://沿着左指针访问沿途经过的根节点,同时将右指针进栈,以便在递归访//问左子树完成后能得到右子树的根节点的地址,如此重复进行,直到栈空。void preOrderTree(BSTreeNode *cnode){Stack s;s.top=0;while( cnode || !isEmpty(&s)){if(cnode){printf("%d,",cnode->m_value);//输出节点if(cnode->m_pRight){push(&s,cnode->m_pRight);//压入右子树节点}cnode = cnode->m_pLeft;}else{cnode = pop(&s);}}}//Description:非递归中序遍历//Algorithm://先沿着左指针走到二叉树中最左下的结点,即左指针为空的结点,将沿//途经过的根节点,指针进栈。当左指针为空时,从栈中取出根节点访问,然后再跳//到右子树上。void inOrderTree(BSTreeNode *cnode){Stack s;s.top = 0;//初始化栈while(cnode || !isEmpty(&s)){while(cnode){//将沿途的的左孩子压栈push(&s,cnode);cnode = cnode->m_pLeft;}cnode=pop(&s);//访问该节点printf("%d,",cnode->m_value);//访问右子树cnode = cnode->m_pRight;}}//Description:非递归的后序遍历//Algorithm:先沿着左指针走到二叉树中最左下的结点,将沿途经过的根节点指针进//栈,若右子树为空,则弹栈并访问根节点,否则,跳到右子树上void postOrderTree(BSTreeNode *cnode){int flag[20]={0};//用于判断该节点的右子树是否已经被访问过了!Stack s;s.top=0;while(cnode || !isEmpty(&s)){while(cnode){push(&s,cnode);flag[s.top-1]=0;//注意在这里赋初值!而不是在一开始!cnode = cnode->m_pLeft;}cnode = pop(&s);if(cnode->m_pRight && flag[s.top] ==0){push(&s,cnode);flag[s.top-1]=1;//标记该节点的右子树已经被访问了cnode = cnode->m_pRight;}else{printf("%d,",cnode->m_value);cnode = NULL;//这个地方值得注意!让其递归向上。}}}int main(){BSTreeNode *tree = create();preOrderTree(tree);printf("\n");inOrderTree(tree);printf("\n");postOrderTree(tree);printf("\n");destroy(tree);return 0;}

感谢 http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810055.html 和数据结构课程 为我写这篇文章提供参考。

如果转载请注明 blog.csdn.net/whuslei

(全文完)