虽然我们能用递归创建二叉树,但是我们是否真正的理解真正的递归过程呢,其实,递归函数的内部还是挺复杂的,想真正弄明白递归也是要下一番功夫的,虽然说,递归算法有效的减少了某些问题的编程,但是它只能简化程序编码,却不能降低程序的时间和空间复杂度,相反,由于执行过程依赖函数或过程的重复调用,会增加函数的时间复杂度.而且返回函数的地址保存需要占用系统栈,从而增加的空间的复杂度。下面是我用栈实现了二叉树的非递归创建.
算法思想:首先,我们对二叉树进行扩展,然后按先序遍历的顺序输入节点的信息,然后我们设置一个标志位flag,如果flag=0,创建当前节点的左孩子节点,当flag=1时,创建当前节点的右孩子节点.具体的分为以下四种情况:
1.当前要创建的节点值为'#',并且flag=1,说明当前节点的父节点的左右孩子已经创建完毕,应将栈顶元素出栈,如果出栈的元素与栈顶的元素的右孩子相同,说明当前节点的父节点的左右孩子也创建完毕.栈顶元素继续出栈,直到栈顶的元素的右孩子和出栈的元素不相同.
2.当前要创建的节点值'#',并且flag=0,说明当前节点的父节点的左孩子已经创建完毕,转向创建右孩子,把flag置为1;
3.当前要创建的节点值不等于'#',并且flag=0,创建当前节点 并作为栈顶元素的左孩子,同时把当前节点入栈.(保存节点,创建右孩子).
4.当前要创建的节点值不等于'#',并且flag=1,创建当前节点并作为栈顶元素的右孩子.同时把当前节点入栈.
代码如下:
/**************树的结构体*********************/ #include <stdio.h> #include <stdlib.h> #define N 50 typedef struct treenode { char data; struct treenode *lChild,*rChild; }BiTNode,*BiTree; BiTree creatTree1() { BiTree stack[N],root,newnode,t,m; //stack[N]定义堆栈; char data[N],*p; int flag=0,top=0; scanf("%s",data); p=data; newnode=(BiTree)malloc(sizeof(BiTNode)); if(newnode == NULL) { return; } newnode->data=*p; p++; newnode->lChild = NULL; newnode->rChild = NULL; stack[top++]=newnode;root=newnode; //根节点先入栈 while(*p!='\0') { if(*p == '#' && flag == 0) { flag=1; } else if(*p == '#' && flag == 1) { t=stack[--top]; while(stack[top-1]->rChild == t) { t=stack[--top]; } } else { newnode=(BiTree)malloc(sizeof(BiTNode)); if(newnode == NULL) { return; } newnode->data=*p; if(flag == 0) { stack[top-1]->lChild=newnode; stack[top++]=newnode; } else { stack[top-1]->rChild=newnode; flag=0; stack[top++]=newnode; } } p++; } return root; }