二叉树先序、中序、后序遍历的非递归实现,纯c代码

       遍历是二叉树操作的基础,在学习数据结构的过程中,很多人对递归遍历烂熟于心而忽略了非递归方式。非递归相对于递归有更高的效率而且不会出现递归可能产生的栈溢出,这里我们采用非递归的方式来进行二叉树的遍历,以下是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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值