A question about how to build a binary tree from its front traval sequence and middle travel sequence

know everything about the binary tree can do it easily

Posted by Maizi on 2016-09-15 with time read

二叉树相关的算法问题

问题描述如下:

给定一棵二叉树的先序遍历和中序遍历的结果,怎么样获取其后续遍历的结果

算法描述:


算法分析:如果某个数组的元素顺序是某棵二叉树的先续遍历的顺序,那么从数组的第一个元素依次向后取元素可以重建这棵二叉树.

①从数组的第一个元素依次向后取元素重建这棵二叉树.

③后续遍历 中重建的二叉树.

最后贴上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <stdlib.h>
typedef struct btree bt;
//二叉树的节点结构定义
struct btree {
int _val;
int _count;//此处优化结构,当元素重复时将该节点的计数加一
bt *_lc;
bt *_rc;
};
/**
* 挂载节点
* @param head 二叉树的根节点的指针
* @param val 待插叙节点的值
*/
void insert(bt const * const head, int const val) {
bt *node = malloc(sizeof(bt));
node->_val = val;
node->_count = 1;
node->_lc = NULL;
node->_rc = NULL;
bt *tmp = head;
while (1) {
if (tmp->_val == val) {
tmp->_count++;
return;
} else if (tmp->_val > val) {
if (tmp->_lc == NULL)
break;
else
tmp = tmp->_lc;
} else {
if (tmp->_rc == NULL)
break;
else
tmp = tmp->_rc;
}
}
if (tmp->_val > val)
tmp->_lc = node;
else
tmp->_rc = node;
}
/**
* 构建二叉树
* @param arr 构建二叉树的输入-数组
* @param len 数组的长度
* @return 二叉树根节点的指针
*/
bt *buildTree(int const * const arr, size_t const len) {
bt *head = malloc(sizeof(bt));
head->_val = *(arr + len - 1);
head->_count = 1;
head->_lc = NULL;
head->_rc = NULL;
int i;
for (i = 1; i < len; ++i) {
insert(head, *(arr + i));
}
return head;
}
/**
* 中序遍历(采用的递归算法)
* @param node 当前的"根"节点指针
*/
void travelMidSeq(bt const * const node) {
if (node->_lc != NULL)
travelMidSeq(node->_lc);
int i;
int len = node->_count;
for (i = 0; i < len; ++i)
printf("%d ", node->_val);
if (node->_rc != NULL)
travelMidSeq(node->_rc);
}
/**
* 释放资源(递归算法)---实质就是后续遍历的算法
* @param node 当前需要处理的节点指针
* @param arr 要排序的数组的指针
*/
void releaseTreeAndCheck(bt *node) {
if (node->_lc != NULL)
releaseTreeAndCheck(node->_lc);
if (node->_rc != NULL)
releaseTreeAndCheck(node->_rc);
printf("%d ", node->_val);
free(node);
}
/**
* 打印数组
* @param arr 数组的指针
* @param len 数组的长度
*/
void print(int const * const arr, size_t const len) {
int i;
printf("the front travel sequence of the tree:\n");
for (i = 0; i < len; ++i)
printf("%d ", *(arr + i));
}
int main(void) {
int arr[] = {8, 4, 2, 1, 3, 6, 5, 7, 12, 10, 9, 11, 14, 13, 15};
size_t len = sizeof(arr) / sizeof(int);
print(arr, len);
bt *tree = buildTree(arr, len);
printf("\nmiddle sequence travel result :\n");
travelMidSeq(tree);
printf("\nback sequence travel result :\n");
releaseTreeAndCheck(tree);
return 0;
}

附上测试结果:

1
2
3
4
5
6
the front travel sequence of the tree:
8 4 2 1 3 6 5 7 12 10 9 11 14 13 15
middle sequence travel result :
1 2 3 4 5 6 7 9 10 11 12 13 14 15 15
back sequence travel result :
1 3 2 5 9 11 10 13 14 12 7 6 4 15


2016-09-15
— Maizi