//2020-04-30
//注意c的结构体赋值并非是传递结构体的引用(指针)
//js和Java写多了容易漏掉这个东西
/**
* 后序遍历:当返回根结点时需要判断是左孩子还是右孩子返回,两种实现方式:
* 1.使用变量记录上一次访问的结点
* 2.创建新的结构,添加tag字段标识结点的左右孩子是否访问,当进入根节点的左右孩子时,无论此时左右是否被访问,
* 都应该设置相应的标志,因为当左右孩子返回根结点时,返回的孩子分支树一定已经被访问过了, 当访问了右孩子时其左孩子一定被访问
*/
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
#define LEFT 0
#define RIGHT 1
typedef int Elem;
typedef struct BTNode {
Elem e;
struct BTNode * lChild;
struct BTNode * rChild;
} * BTNode;
typedef struct {
BTNode node;
//标识当前节点是否被访问
int tag;
} TNode;
BTNode ancestor(BTNode root, Elem p, Elem q);
BTNode buildTree(Elem [], int , int , Elem [], int , int );
void preOrder(BTNode);
void inOrder(BTNode);
void postOrder(BTNode);
int i = 1;
int main(void) {
Elem A[] = {1,2,4,5,3,6,7};
Elem B[] = {4,2,5,1,6,3,7};
BTNode obj = buildTree(A, 0, 6, B, 0, 6);
postOrder(obj);
//printf("%d", ancestor(obj, 4, 6)->e);
return 0;
}
BTNode ancestor(BTNode root, Elem p, Elem q) {
TNode stack[MAX], ancestor[MAX];
int top = -1, top_a = -1;
while(root != NULL || top > -1) {
if(root) {
stack[++top] = (TNode){root, LEFT};
root = root->lChild;
} else {
TNode t = stack[top];
if(t.node->rChild && t.tag == LEFT) {
t.tag = RIGHT;
root = root->rChild;
} else {
--top;
if(t.node->e == p) {
while(top_a < top) {
top_a++;
ancestor[top_a] = stack[top_a];
}
} else if(t.node->e == q) {
break;
}
root = NULL;
}
}
}
int i = 0;
while(stack[i].node == ancestor[i].node) ++i;
return stack[--i].node;
}
BTNode buildTree(Elem A[], int sa, int ea, Elem B[], int sb, int eb) {
BTNode node = (BTNode)malloc(sizeof(struct BTNode) * 1);
node->e = A[sa];
int i = sb;
for(i; A[sa] != B[i]; ++i);
int ll = i - sb;
int rr = eb - i;
if(ll > 0) {
node->lChild = buildTree(A, sa + 1, sa + ll, B, sb, sb + ll - 1);
} else {
node->lChild = NULL;
}
if(rr > 0) {
node->rChild = buildTree(A, sa + ll + 1, ea, B, sb + ll + 1, eb);
} else {
node->rChild = NULL;
}
return node;
}
void preOrder(BTNode T) {
if(T == NULL) return;
printf("%d ", T -> e);
preOrder(T->lChild);
preOrder(T->rChild);
}
void inOrder(BTNode T) {
if(T == NULL) return;
inOrder(T->lChild);
printf("%d ", T -> e);
inOrder(T->rChild);
}
void postOrder(BTNode T) {
TNode * stack[MAX];
BTNode root = T;
int top = -1;
while(root != NULL || top > -1) {
if(root ) {
TNode * t = (TNode *)malloc(sizeof(TNode));
t->node = root;
t->tag = LEFT;
stack[++top] = t;
root = root->lChild;
} else {
TNode * t = stack[top];
if(t->node->rChild != NULL && t->tag == LEFT) {
t->tag = RIGHT;
root = t->node->rChild;
} else {
--top;
printf("%d ", t->node->e);
root = NULL;
}
}
}
}
二叉树的后序非递归及使用后序获取两个接点的第一个共同祖先
最新推荐文章于 2022-10-12 20:28:44 发布