二叉树的先序、中序、后序非递归算法C语言实现

二叉树的先序、中序、后序非递归算法C语言实现

一、 链式栈结构源码

1. 头文件:linkedstack.h

#ifndef TREE
#define TREE
#include "bitree.h"
#endif

// 栈结点类型
struct StackNode {
	struct BiTNode *data;
	struct StackNode *next;
};

// 链式栈类型
struct LinkedStack {
	struct StackNode *top;
	int size;
};

// 得到一个空的链式栈
struct LinkedStack *getLinkedStack();

// 销毁链式栈
void destroyLinkedStack(struct LinkedStack *lstack);

//  入栈
void push(struct LinkedStack *lstack, struct BiTNode *topData);

// 出栈
struct BiTNode *pop(struct LinkedStack *lstack);

// 判断栈是否为空
bool stackIsEmpty(struct LinkedStack *lstack);

// 得到栈顶元素,但是栈顶不出栈
struct BiTNode *getTop(struct LinkedStack *lstack);

2. 栈实现:linkedstack.c

#include "linkedstack.h"
#include <stdbool.h>
#include <stdlib.h>

struct LinkedStack *getLinkedStack() {
	struct LinkedStack *lstack = (struct LinkedStack *)
		malloc(sizeof(struct LinkedStack));
	if (lstack == NULL)
		exit(EXIT_FAILURE);

	lstack->top = NULL;
	lstack->size = 0;

	return lstack;
}

static void freeNodes(struct StackNode *first) {
	struct StackNode *next = NULL;
	while (first) {
		next = first->next;
		free(first);
		first = next;
	}
}

void destroyLinkedStack(struct LinkedStack *lstack) {
	freeNodes(lstack->top);
	free(lstack);
}

void push(struct LinkedStack *lstack, struct BiTNode *topData) {
	struct StackNode *oldTop = lstack->top;
	lstack->top = (struct StackNode *) malloc(sizeof(struct StackNode));
	if (lstack->top == NULL)
		exit(EXIT_FAILURE);
	lstack->top->data = topData;
	lstack->top->next = oldTop;
	lstack->size++;
}

bool stackIsEmpty(struct LinkedStack *lstack) {
	return 0 == lstack->size;
}

struct BiTNode *pop(struct LinkedStack *lstack) {
	if (stackIsEmpty(lstack))
		return NULL;

	struct StackNode *oldTop = lstack->top;
	lstack->top = oldTop->next;
	struct BiTNode *topData = oldTop->data;
	free(oldTop);
	lstack->size--;

	return topData; 
}

struct BiTNode *getTop(struct LinkedStack *lstack) {
	if (stackIsEmpty(lstack))
		return NULL;

	return lstack->top->data;
}

二、二叉树三种非递归遍历实现源码

1. 头文件:bitree.h

#include <stdbool.h>

typedef char TElemType;

struct BiTNode {
	TElemType data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
};

// 创建二叉树
struct BiTNode *createBiTree();

// 非递归先序遍历二叉树
void preOrderTraverse(struct BiTNode *root);

// 非递归中序遍历二叉树
void inOrderTraverse(struct BiTNode *root);

// 非递归后序遍历二叉树
void postOrderTraverse(struct BiTNode *root);

// 销毁二叉树
void destroyBiTree(struct BiTNode *root);

2. 遍历实现:bitree.c

#ifndef TREE
#define TREE
#include "bitree.h"
#include "linkedstack.h"
#include <stdio.h>
#include <stdlib.h>
#endif

struct BiTNode *createBiTree() {
	printf("请输入根节点的值:");
	TElemType data = getchar();
	getchar();

	if (data == '#')
		return NULL;

	struct BiTNode *root = (struct BiTNode *) 
		malloc(sizeof(struct BiTNode));
	if (root == NULL)
		exit(EXIT_FAILURE);
	root->data = data;

	root->lchild = createBiTree();
	root->rchild = createBiTree();

	return root;
}

// 非递归实现先序遍历
void preOrderTraverse(struct BiTNode *root) {
	struct LinkedStack *lstack = getLinkedStack();
	
	// 将根节点入栈
	push(lstack, root);
	struct BiTNode *top = NULL;
	while (!stackIsEmpty(lstack)) {
		while ((top = getTop(lstack)) && top != NULL) {
			printf("%c\n", top->data);
			push(lstack, top->lchild);
		}
		pop(lstack);
		if (!stackIsEmpty(lstack)) {
			top = pop(lstack);
			push(lstack, top->rchild);
		}
	}
	destroyLinkedStack(lstack);
}

// 非递归实现中序遍历
void inOrderTraverse(struct BiTNode *root) {
	struct LinkedStack *lstack = getLinkedStack();
	// 将根节点入栈
	push(lstack, root);

	struct BiTNode *top = NULL;
	while (!stackIsEmpty(lstack)) {
		while ((top = getTop(lstack)) && top != NULL) {
			push(lstack, top->lchild);
		}
		pop(lstack);
		if (!stackIsEmpty(lstack)) {
			top = pop(lstack);
			printf("%c\n", top->data);
			push(lstack, top->rchild);
		}
	}
	destroyLinkedStack(lstack);
}

// 使用双栈法实现后序遍历的非递归遍历
void postOrderTraverse(struct BiTNode *root) {
	struct LinkedStack *lstack1 = getLinkedStack();
	struct LinkedStack *lstack2 = getLinkedStack();

	// 将根节点入栈
	push(lstack1, root);
	struct BiTNode *top = NULL;
	while (!stackIsEmpty(lstack1)) {
		top = pop(lstack1);
		push(lstack2, top);

		if (top->lchild != NULL)
			push(lstack1, top->lchild);
		if (top->rchild != NULL)
			push(lstack1, top->rchild);
	}

	while (!stackIsEmpty(lstack2)) {
		top = pop(lstack2);
		printf("%c\n", top->data);
	}
    
    destroyLinkedStack(lstack1);
    destroyLinkedStack(lstack2);
}

void destroyBiTree(struct BiTNode *root) {
	if (root != NULL) {
		destroyBiTree(root->lchild);
		destroyBiTree(root->rchild);
		free(root);
	}
}

三、main函数

#include "bitree.h"
#include <stdio.h>

int main(void) {
	struct BiTNode *root = createBiTree();
	preOrderTraverse(root);
	inOrderTraverse(root);
	postOrderTraverse(root);
	destroyBiTree(root);
	return 0;
}

四、Makefile文件

TARGET=run
CC=gcc -std=c99
OBJECT=main.o bitree.o linkedstack.o

$(TARGET):$(OBJECT)
	  $(CC) $(OBJECT) -o $(TARGET)
main.o:main.c
	  $(CC) -c main.c -o main.o
bitree.o:bitree.c
	  $(CC) -c bitree.c -o bitree.o
linkedstack.o:linkedstack.c
	  $(CC) -c linkedstack.c -o linkedstack.o
.PHONY:clean
clean:
	rm -rf *.o
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值