二叉树的概念就不多讲,直接上代码:
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 10
#define INCREASE_SIZE 10
typedef struct Node
{
char data;
struct Node *left;
struct Node *right;
int lflag;
int rflag;
}Node, *BTree;
typedef struct
{
Node **base;
int top;
int curlen;
}NodeStack;
void init_stack(NodeStack *s)
{
s->base = (Node**)malloc(STACK_INIT_SIZE*sizeof(Node*));
if (!s->base)
{
printf("Init stack error\n");
return ;
}
s->top = 0;
s->curlen = STACK_INIT_SIZE;
}
void free_stack(NodeStack *s)
{
if (s->base)
{
free(s->base);
s->base = NULL;
s->top = s->curlen = 0;
}
}
int is_stack_empty(NodeStack s)
{
return s.top <= 0;
}
int is_stack_full(NodeStack s)
{
return s.top >= s.curlen;
}
void push_node(NodeStack *s, Node *pnode)
{
if (is_stack_full(*s))
{
Node **tmp;
tmp = (Node**)realloc(s->base, (s->curlen+INCREASE_SIZE)*sizeof(Node*));
if (!tmp)
{
printf("push error\n");
free_stack(s);
return ;
}
s->curlen += INCREASE_SIZE;
}
(s->base)[s->top] = pnode;
(s->top)++;
}
Node* pop_node(NodeStack *s)
{
if (is_stack_empty(*s))
{
return NULL;
}
(s->top)--;
return (s->base)[s->top];
}
//先序创建二叉树
BTree dlr_create_tree()
{
char data;
printf("Enter the root node:\n");
scanf("%c", &data);
getchar();
if (data == '#')
{
return NULL;
}
Node* rootnode;
rootnode = (Node*)malloc(sizeof(Node));
if (!rootnode)
{
printf("dlr_create_tree error\n");
return NULL;
}
rootnode->data = data;
rootnode->left = NULL;
rootnode->lflag = 0;
rootnode->right = NULL;
rootnode->rflag = 0;
Node *curnode;
curnode = rootnode;
NodeStack s;
init_stack(&s);
while (1)
{
if (!curnode->lflag)
{
curnode->lflag = 1;
printf("Enter the left node of %c:\n",curnode->data);
char c;
scanf("%c", &c);
getchar();
if (c != '#')
{
Node *curleft;
curleft = (Node*)malloc(sizeof(Node));
if (curleft)
{
curleft->data = c;
curleft->left = NULL;
curleft->lflag = 0;
curleft->right = NULL;
curleft->rflag = 0;
curnode->left = curleft;
push_node(&s, curnode);
curnode = curleft;
continue;
}
}
}
if (!curnode->rflag)
{
curnode->rflag = 1;
printf("Enter the right node of %c:\n", curnode->data);
char c;
scanf("%c", &c);
getchar();
if (c != '#')
{
Node *curright;
curright = (Node*)malloc(sizeof(Node));
if (curright)
{
curright->data = c;
curright->left = NULL;
curright->lflag = 0;
curright->right = NULL;
curright->rflag = 0;
curnode->right = curright;
curnode = curright;
}
}
else
{
if (is_stack_empty(s))
{
break;
}
else
{
curnode = pop_node(&s);
}
}
}
}
free_stack(&s);
return rootnode;
}
//先序遍历二叉树
void dlr_vist_tree(BTree t)
{
if (!t)
{
return;
}
NodeStack s;
init_stack(&s);
Node *curnode;
curnode = t;
while (1)
{
printf("%3c", curnode->data);
if (curnode->left)
{
push_node(&s, curnode);
curnode = curnode->left;
continue;
}
if (curnode->right)
{
curnode = curnode->right;
}
else
{
Node *tmp = NULL;
while (!is_stack_empty(s))
{
tmp = pop_node(&s);
if (tmp->right)
{
curnode = tmp->right;
break;
}
}
if (is_stack_empty(s) && (!tmp || !tmp->right))
{
break;
}
}
}
free_stack(&s);
printf("\n");
}
//中序遍历二叉树
void ldr_vist_tree(BTree t)
{
if (!t)
{
return;
}
NodeStack s;
Node *curnode;
curnode = t;
init_stack(&s);
while (1)
{
if (curnode->left)
{
push_node(&s, curnode);
curnode = curnode->left;
continue;
}
printf("%3c", curnode->data);
if (curnode->right)
{
curnode = curnode->right;
}
else
{
Node *tmp;
tmp = NULL;
while (!is_stack_empty(s))
{
tmp = pop_node(&s);
printf("%3c", tmp->data);
if (tmp->right)
{
curnode = tmp->right;
break;
}
}
if (is_stack_empty(s) && (!tmp || !(tmp->right)))
{
break;
}
}
}
printf("\n");
free_stack(&s);
}
//释放二叉树
void free_tree(BTree t)
{
if (!t)
{
return;
}
Node *curnode;
curnode = t;
NodeStack s;
init_stack(&s);
while (1)
{
if (curnode->left || curnode->right)
{
push_node(&s, curnode);
if (curnode->left)
{
curnode = curnode->left;
continue;
}
if (curnode->right)
{
curnode = curnode->right;
}
}
else
{
if (is_stack_empty(s))
{
printf("free node %c\n", curnode->data);
free(curnode);
break;
}
Node *tmp;
tmp = pop_node(&s);
if (curnode == tmp->left)
{
tmp->left = NULL;
}
if (curnode == tmp->right)
{
tmp->right = NULL;
}
printf("free node %c\n", curnode->data);
free(curnode);
curnode = tmp;
}
}
free_stack(&s);
}
//后序遍历二叉树
void lrd_vist_tree(BTree t)
{
if (!t)
{
return;
}
Node *curnode;
NodeStack s;
curnode = t;
init_stack(&s);
while (1)
{
if (curnode->lflag || curnode->rflag)
{
if (curnode->lflag && curnode->left)
{
push_node(&s, curnode);
curnode = curnode->left;
continue;
}
if (curnode->rflag && curnode->right)
{
push_node(&s, curnode);
curnode = curnode->right;
continue;
}
else
{
curnode->lflag = curnode->rflag = 0;
}
}
else
{
printf("%3c", curnode->data);
if (is_stack_empty(s))
{
break;
}
Node *tmp = NULL;
while (!is_stack_empty(s))
{
tmp = pop_node(&s);
if (curnode == tmp->left)
{
tmp->lflag = 0;
if (tmp->right)
{
push_node(&s, tmp);
curnode = tmp->right;
}
else
{
tmp->rflag = 0;
curnode = tmp;
}
break;
}
else if(curnode == tmp->right)
{
tmp->rflag = 0;
curnode = tmp;
break;
}
}
}
}
free_stack(&s);
printf("\n");
}
int main()
{
BTree bt;
bt = dlr_create_tree();
printf("DLR visit:\n");
dlr_vist_tree(bt);
printf("LDR visit:\n");
ldr_vist_tree(bt);
printf("LRD visti:\n");
lrd_vist_tree(bt);
free_tree(bt);
return 0;
}