遍历是二叉树操作的基础,在学习数据结构的过程中,很多人对递归遍历烂熟于心而忽略了非递归方式。非递归相对于递归有更高的效率而且不会出现递归可能产生的栈溢出,这里我们采用非递归的方式来进行二叉树的遍历,以下是C代码,水平有限,若有问题,不吝赐教。
btree.c
/************************************************************************/
/* 普通二叉树 */
/* ziven 20131022 */
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
typedef struct _bitree_node
{
char data;
struct _bitree_node *lchild;
struct _bitree_node *rchild;
}bitree_node_t, *pbitree_t;
#define VISIT_BNODE(_node) \
printf("%c ", _node->data)
#define GET_BSTACK_TOP(_s) \
(bitree_node_t *)stack_top_get(_s)
void bi_tree_in_order_re(pbitree_t root)
{
if (root != NULL)
{
bi_tree_in_order_re(root->lchild);
printf("%c ", root->data);
bi_tree_in_order_re(root->rchild);
}
}
void bi_tree_in_order(pbitree_t root)
{
bitree_node_t *node = NULL;
pstack_t stack = stack_new();
node = root;
do
{
if (node->lchild != NULL)
{
stack_push(stack, node);
node = node->lchild;
}
else
{
VISIT_BNODE(node);
while (node->rchild == NULL)
{
if (stack_is_empty(stack))
break;
stack_pop(stack, (void **)&node);
VISIT_BNODE(node);
}
node = node->rchild;
}
}
while (node != NULL || !stack_is_empty(stack));
free(stack);
}
void bi_tree_in_order_way2(pbitree_t root)
{
bitree_node_t *node = NULL;
pstack_t stack = stack_new();
node = root;
do
{
while (node != NULL)
{
stack_push(stack, node);
node = node->lchild;
}
if (!stack_is_empty(stack))
{
stack_pop(stack, (void **)&node);
VISIT_BNODE(node);
node = node->rchild;
}
} while (node != NULL || !stack_is_empty(stack));
free(stack);
}
void bi_tree_pre_order_re(pbitree_t root)
{
if (root == NULL)
{
return;
}
VISIT_BNODE(root);
bi_tree_pre_order_re(root->lchild);
bi_tree_pre_order_re(root->rchild);
}
void bi_tree_pre_order(pbitree_t root)
{
bitree_node_t *node = root;
pstack_t stack = stack_new();
do
{
while (node != NULL)
{
VISIT_BNODE(node);
stack_push(stack, node);
node = node->lchild;
}
if (!stack_is_empty(stack))
{
stack_pop(stack, (void **)&node);
node = node->rchild;
}
}while(node != NULL || !stack_is_empty(stack));
free(stack);
}
void bi_tree_after_order_re(pbitree_t root)
{
if (root != NULL)
{
bi_tree_after_order_re(root->lchild);
bi_tree_after_order_re(root->rchild);
VISIT_BNODE(root);
}
}
void bi_tree_after_order(pbitree_t root)
{
bitree_node_t *node = root;
bitree_node_t *prenode = NULL;
int rt = 0;
pstack_t stack = stack_new();
while (node != NULL || !stack_is_empty(stack))
{
while (node != NULL)
{
stack_push(stack, node);
node = node->lchild;
}
if (!stack_is_empty(stack))
{
node = GET_BSTACK_TOP(stack);
if (node->rchild == NULL || node->rchild == prenode)
{
VISIT_BNODE(node);
stack_pop(stack, (void **)&node);
prenode = node;
node = NULL;
}
else
{
node = node->rchild;
}
}
}
free(stack);
}
/*二叉树的左右子树翻转*/
void bi_tree_trans(pbitree_t root)
{
bitree_node_t *node = root;
bitree_node_t *prenode = NULL;
bitree_node_t *tnode = NULL;
pstack_t stack = stack_new();
while (node != NULL || !stack_is_empty(stack))
{
while (node != NULL)
{
stack_push(stack, node);
node = node->lchild;
}
if (!stack_is_empty(stack))
{
node = GET_BSTACK_TOP(stack);
if (node->rchild == NULL || node->rchild == prenode)
{
tnode = node->lchild;
node->lchild = node->rchild;
node->rchild = tnode;
stack_pop(stack, (void **)&node);
prenode = node;
node = NULL;
}
else
{
node = node->rchild;
}
}
}
free(stack);
}
void bitree_test()
{
pbitree_t tree;
bi_tree_create(&tree);putchar('\n');
printf("二叉树的遍历\n");
bi_tree_in_order_re(tree);putchar('\n');
bi_tree_in_order(tree);putchar('\n');
bi_tree_in_order_way2(tree);printf("\n-----------------\n");
bi_tree_pre_order_re(tree);putchar('\n');
bi_tree_pre_order(tree);printf("\n-----------------\n");
bi_tree_after_order_re(tree);putchar('\n');
bi_tree_after_order(tree);printf("\n-----------------\n");
printf("二叉树翻转\n");
bi_tree_trans(tree);
bi_tree_pre_order(tree);putchar('\n');
bi_tree_in_order(tree);putchar('\n');
bi_tree_after_order(tree);putchar('\n');
bi_tree_trans(tree);putchar('\n');
bi_tree_pre_order(tree);printf("\n-----------------\n");
}
static char g_s[20] = "ABD.G..E..C.FHI....";
static int bi_tree_i = 0;
void bi_tree_create(pbitree_t *bt) /*先序创建二叉树*/
{
char ch;
ch = g_s[bi_tree_i++];
if (ch == '.')
*bt = NULL;
else
{
*bt = (pbitree_t)malloc(sizeof(bitree_node_t));
(*bt)->data = ch;
bi_tree_create(&((*bt)->lchild));
bi_tree_create(&((*bt)->rchild));
}
}
int main()
{
bitree_test();
}
stack.c
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
pstack_t stack_new()
{
pstack_t stack = (pstack_t)malloc(sizeof(stack_node_t));
stack->elem = NULL;
stack->next = NULL;
return stack;
}
int stack_push(pstack_t stack, void *v)
{
stack_node_t *node = NULL;
node = (stack_node_t *)malloc(sizeof(stack_node_t));
node->elem = v;
node->next = stack->next;
stack->next = node;
return 0;
}
int stack_pop(pstack_t stack, void **v)
{
stack_node_t *node = NULL;
if (stack == NULL || stack->next == NULL)
{
return -1;
}
node = stack->next;
*v = node->elem;
stack->next = node->next;
free(node);
return 0;
}
int stack_is_empty(pstack_t stack)
{
if (stack->next == NULL)
{
return 1;
}
else
{
return 0;
}
}
void *stack_top_get(pstack_t stack)
{
return stack->next == NULL ? NULL : stack->next->elem;
}