采用先序序列输入,二叉链表存储结构,非递归方式建立二叉树。
对于非递归算法建立二叉树可以参考迷宫算法给出;
- #include<stdio.h>
- #include<stdlib.h>
- #include<conio.h>
- typedef struct tree
- {
- char ch;
- struct tree *lchild;
- struct tree *rchild;
- int flag;
- }TREE;
- typedef struct
- {
- TREE *elem[30];
- int top;
- }STACK;
- void initStack(STACK *S);
- int push(STACK *S, TREE *x);
- int pop(STACK *S, TREE **x);
- int Pass(TREE *p);
- TREE *createTree();
- void fristRoot(TREE *root);
- void middleRoot(TREE *root);
- void lastRoot(TREE *root);
- void destroyTree(TREE *root);
- int main()
- {
- TREE *root;
- root = createTree();
- printf("\n先序:\n");
- fristRoot(root);
- printf("\n中序:\n");
- middleRoot(root);
- printf("\n后序:\n");
- lastRoot(root);
- printf("\n");
- destroyTree(root);
- return 0;
- }
- void initStack(STACK *S)
- {
- S->top = -1;
- }
- int push(STACK *S, TREE *x)
- {
- if (S->top >= 29)
- return 0;
- S->top++;
- S->elem[S->top] = x;
- return 1;
- }
- int pop(STACK *S, TREE **x)
- {
- if (S->top < 0)
- return 0;
- *x = S->elem[S->top];
- S->top--;
- return 1;
- }
- int Pass(TREE *p)
- {
- if (p->lchild == NULL)
- if (p->rchild == NULL)
- return 0;
- else
- if (p->rchild->flag)
- return 0;
- else
- return 2;
- else
- if (p->lchild->flag)
- if (p->rchild == NULL)
- return 0;
- else
- if (p->rchild->flag)
- return 0;
- else
- return 2;
- else
- if (p->rchild == NULL)
- return -1;
- else
- if (p->rchild->flag)
- return -1;
- else
- return 1;
- }
- TREE *createTree()
- {
- char ch;
- STACK S;
- TREE *root, *p, *q, *temp;
- int i, ret;
- initStack(&S);
- root = (TREE *)malloc(sizeof(TREE));
- printf("Please input string:\n");
- ch = getche();
- root->ch = ch;
- p = root;
- p->lchild = p->rchild = p;
- p->flag = 0;
- push(&S, p);
- i = 0;
- do{
- if( (ret = Pass(p) ) > 0 )
- {
- ch = getche();
- if(ch != ' ')
- {
- q = (TREE *)malloc(sizeof(TREE));
- q->ch = ch;
- q->lchild = q->rchild = q;
- q->flag = 0;
- push(&S, q);
- }
- else
- q = NULL;
- if (ret == 1)
- p->lchild = q;
- else if (ret == 2)
- p->rchild = q;
- }
- else
- pop(&S, &temp);
- if(S.top > -1)
- {
- p->flag = 1;
- if(p->lchild != p && p->rchild == p)
- p->flag = 0;
- p = S.elem[S.top];
- }
- }while(S.top > -1);
- return root;
- }
- void fristRoot(TREE *root)
- {
- TREE *p;
- STACK S;
- initStack(&S);
- p = root;
- while( p || S.top > -1)
- {
- while(p)
- {
- printf("%c ",p->ch);
- push(&S, p);
- p = p->lchild;
- }
- if(!p)
- {
- pop(&S, &p);
- p = p->rchild;
- }
- }
- }
- void middleRoot(TREE *root)
- {
- TREE *p;
- STACK S;
- initStack(&S);
- p = root;
- while(p || S.top > -1)
- {
- if(p)
- {
- push(&S, p);
- p = p->lchild;
- }
- else
- {
- pop(&S, &p);
- printf("%c ",p->ch);
- p = p->rchild;
- }
- }
- }
- void lastRoot(TREE *root)
- {
- TREE *p, *q;
- STACK S;
- initStack(&S);
- p = root;
- while(p || S.top != -1)
- {
- while(p)
- {
- push(&S, p);
- p = p->lchild;
- }
- if(S.top > -1)
- {
- p = S.elem[S.top];
- if(p->rchild == NULL || p->rchild == q)
- {
- printf("%c ",p->ch);
- q = p;
- S.top--;
- p = NULL;
- }
- else
- p = p->rchild;
- }
- }
- }
- void destroyTree(TREE *root)
- {
- if (root != NULL)
- {
- destroyTree(root->lchild);
- destroyTree(root->rchild);
- free(root);
- }
- }
二叉树的定义:
flag主要用于标记该节点是否处理过; 对于Pass函数(改函数主要判断其左右孩子是否处理)的详细解释:
- typedef struct tree
- {
- char ch;
- struct tree *lchild;
- struct tree *rchild;
- int flag;
- }TREE;
假设p为根节点, 其左孩子为p->lchild 右孩子为p->rchild
条件 | 返回值 | ||
1 | p->lchild == NULL && p->rchild == NULL | 不可通过 | 0 |
2 | p->lchild == NULL && p->rchild != NULL && p->rchild->flag == 0 | 右子树可通过 | 2 |
3 | p->lchild == NULL && p->rchild != NULL && p->rchild->flag == 1 | 不可通过 | 0 |
4 | p->lchild != NULL && p->lchild->flag == 0 && p->rchild == NULL | 此情况不会发生 | |
5 |
p->lchild != NULL && p->lchild->flag == 0 && p->rchild != NULL && p->rchild->flag == 0 |
左子树可通过 | 1 |
6 |
p->lchild!=NULL && p->lchild->flag == 0 && p->rchild != NULL && p->rchild->flag == 1 |
此情况不会发生 | |
7 | p->lchild!=NULL && p->lchild->flag == 1 && p->rchild == NULL | 不可通过 | 0 |
8 |
p->lchild!=NULL && p->lchild->flag == 1 p->rchild != NULL && p->rchild->flag == 0 |
右子树可通过 | 2 |
9 |
p->lchild!=NULL && p->lchild->flag == 1 p->rchild != NULL && p->rchild->flag == 1 |
不可通过 | 0 |