二叉树的遍历(前序+中序+后序的递归和递推实现)
以以下二叉树为例,展现以下前序、中序、后序(层序)的结果。
层序代码就不实现了,用队列采用广度优先搜索即可。
四种遍历的思想:
前序遍历:根节点 -> 左子树 -> 右子树 (根左右)
中序遍历:左子树 -> 根结点 -> 右子树 (左根右)
后序遍历:左子树 -> 右子树 -> 根结点 (左右根)
层序遍历:从根开始一层层从左到右遍历即可。
前序遍历
遍历结果:ABDHEIJCFGK
// 先序遍历(递归)
int searchBinaryTreeByPreOrder1(stBinaryTreeNode * node, char * msg) {
int len = 0;
if (node != NULL) {
msg[len++] = (char) (int) node->data;
len += searchBinaryTreeByPreOrder1(node->lchild, msg + len);
len += searchBinaryTreeByPreOrder1(node->rchild, msg + len);
}
msg[len] = 0;
return len;
}
// 先序遍历(递推)
int searchBinaryTreeByPreOrder2(stBinaryTreeNode * root, char * msg, const int STACK_SIZE) {
stBinaryTreeNodeStack stack;
createStack(&stack, STACK_SIZE);
int len = 0;
stBinaryTreeNode * node = root;
while (node != NULL || !isEmptyStack(&stack)) {
while (node != NULL) {
msg[len++] = (char) (int) node->data;
pushStack(&stack, node);
node = node->lchild;
}
if (!isEmptyStack(&stack)) {
node = popStack(&stack);
node = node->rchild;
}
}
msg[len] = 0;
destoryStack(&stack);
return len;
}
中序遍历
遍历结果:DHBIEJAFCKG
// 中序遍历(递归)
int searchBinaryTreeByMidOrder1(stBinaryTreeNode * node, char * msg) {
int len = 0;
if (node != NULL) {
len += searchBinaryTreeByMidOrder1(node->lchild, msg + len);
msg[len++] = (char) (int) node->data;
len += searchBinaryTreeByMidOrder1(node->rchild, msg + len);
} else {
msg[len] = 0;
}
// msg[len] = 0;
return len;
}
// 中序遍历(递推)
int searchBinaryTreeByMidOrder2(stBinaryTreeNode * root, char * msg, const int STACK_SIZE) {
stBinaryTreeNodeStack stack;
createStack(&stack, STACK_SIZE);
int len = 0;
stBinaryTreeNode * node = root;
while (node != NULL || !isEmptyStack(&stack)) {
while (node != NULL) {
pushStack(&stack, node);
node = node->lchild;
}
if (!isEmptyStack(&stack)) {
node = popStack(&stack);
msg[len++] = (char) (int) node->data;
node = node->rchild;
}
}
msg[len] = 0;
destoryStack(&stack);
return len;
}
后序遍历
遍历结果:HDIJEBFKGCA
// 后序遍历(递归)
int searchBinaryTreeByPostOrder1(stBinaryTreeNode * node, char * msg) {
int len = 0;
if (node != NULL) {
len += searchBinaryTreeByPostOrder1(node->lchild, msg + len);
len += searchBinaryTreeByPostOrder1(node->rchild, msg + len);
msg[len++] = (char) (int) node->data;
}
msg[len] = 0;
return len;
}
// 后序遍历(递推)
int searchBinaryTreeByPostOrder2(stBinaryTreeNode * root, char * msg, const int STACK_SIZE) {
stBinaryTreeNodeStack stack;
createStack(&stack, STACK_SIZE);
int len = 0;
stBinaryTreeNode * node = root;
stBinaryTreeNode * last_node = node;
while (node != NULL || !isEmptyStack(&stack)) {
while (node != NULL) {
pushStack(&stack, node);
node = node->lchild;
}
node = topStack(&stack);
if (node->rchild == NULL || node->rchild == last_node) {
msg[len++] = (char) (int) node->data;
popStack(&stack);
last_node = node;
node = NULL;
} else {
node = node->rchild;
}
}
msg[len] = 0;
destoryStack(&stack);
return len;
}
层序遍历
遍历结果:ABCDEFGHIJK
树结构体和栈的参考代码
// 二叉树节点
typedef struct _stBinaryTreeNode {
void * data; // 保存数据,可以存储数据指针或者地址大小范围内的数值
struct _stBinaryTreeNode * lchild; // 左子节点的地址
struct _stBinaryTreeNode * rchild; // 右子节点的地址
} stBinaryTreeNode;
// 二叉树栈
typedef struct _stBinaryTreeNodeStack {
stBinaryTreeNode ** stack;
int top;
} stBinaryTreeNodeStack;
// 创建栈
void createStack(stBinaryTreeNodeStack * p_stack, const int STACK_SIZE) {
// stBinaryTreeNodeStack * p_stack = (stBinaryTreeNodeStack *) malloc(sizeof(stBinaryTreeNodeStack));
p_stack->stack = (stBinaryTreeNode **) malloc(sizeof(stBinaryTreeNode *) * STACK_SIZE);
p_stack->top = -1;
}
// 释放栈
void destoryStack(stBinaryTreeNodeStack * p_stack) {
free(p_stack->stack);
p_stack->stack = NULL;
p_stack->top = -1;
}
// 判断栈是否为空
int isEmptyStack(stBinaryTreeNodeStack * p_stack) {
return (p_stack->top < 0) ? 1 : 0;
}
// 压栈
void pushStack(stBinaryTreeNodeStack * p_stack, stBinaryTreeNode * node) {
p_stack->stack[++p_stack->top] = node;
}
// 获取栈顶
stBinaryTreeNode * topStack(stBinaryTreeNodeStack * p_stack) {
return isEmptyStack(p_stack) ? NULL : p_stack->stack[p_stack->top];
}
// 出栈
stBinaryTreeNode * popStack(stBinaryTreeNodeStack * p_stack) {
return p_stack->stack[p_stack->top--];
}