A question about how to judge an array is the back sequence of a binary tree

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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#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 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 = len - 2; i >= 0; --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);
}
//记录当前已遍历元素的个数;
int index = 0;
//标记当前是否找到错误元素并记录错误元素的位置
char flag = -1;
/**
* 释放资源(递归算法)---实质就是后续遍历的算法,并校验数组中元素是不是后续遍历的顺序
* @param node 当前需要处理的节点指针
* @param arr 要排序的数组的指针
*/
void releaseTreeAndCheck(bt *node, int const * const arr) {
if (node->_lc != NULL)
releaseTreeAndCheck(node->_lc, arr);
if (node->_rc != NULL)
releaseTreeAndCheck(node->_rc, arr);
if (flag < 0) {
if (*(arr + index) != node->_val)
flag = index;
else
index++;
}
printf("%d ", node->_val);
free(node);
}
/**
* 打印数组
* @param arr 数组的指针
* @param len 数组的长度
*/
void print(int const * const arr, size_t const len) {
int i;
printf("original sequence:\n");
for (i = 0; i < len; ++i)
printf("%d ", *(arr + i));
}
int main(void) {
int arr[] = {1, 3, 2, 5, 7, 9, 4, 9, 11, 10, 13, 15, 14, 12, 8};
//int arr[] = {1, 3, 2, 5, 7, 6, 4, 9, 11, 10, 13, 15, 14, 12, 8};
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, arr);
if (flag >= 0) printf("\nsorry! your input seems not the back sequence of a binary tree...\nthe wrong member from index %d", flag);
else printf("\ncongratulations! your input is the back sequence of a binary tree...");
return 0;
}

附上测试结果:

1
2
3
4
5
6
7
original sequence:
1 3 2 5 7 6 4 9 11 10 13 15 14 12 8
middle sequence travel result :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
back sequence travel result :
1 3 2 5 7 6 4 9 11 10 13 15 14 12 8
congratulations! your input is the back sequence of a binary tree...
1
2
3
4
5
6
7
8
original sequence:
1 3 2 5 7 9 4 9 11 10 13 15 14 12 8
middle sequence travel result :
1 2 3 4 5 7 8 9 9 10 11 12 13 14 15
back sequence travel result :
1 3 2 5 7 4 9 11 10 13 15 14 12 8
sorry! your input seems not the back sequence of a binary tree...
the wrong member from index 5


2016-09-15
— Maizi