30006:不透明整数二叉搜索树
题目
实现拥有结点、支持插入、查找和中序遍历的不透明整数二叉搜索树。
解析
插入沿唯一的搜索路径向下走;遇到相等键时不创建新结点。只有走到空孩子时才分配结点,因此分配失败不会改变树。中序遍历先检查树中结点数是否超过输出容量,再写入输出数组,从而不会出现写入一部分后才发现容量不足的情况。
答案
c
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct IntBst IntBst;
typedef enum {
INT_BST_OK,
INT_BST_INVALID,
INT_BST_OUT_OF_MEMORY
} IntBstResult;
typedef struct BstNode BstNode;
struct BstNode {
int64_t key;
BstNode *left;
BstNode *right;
};
struct IntBst {
BstNode *root;
size_t size;
};
IntBst *int_bst_create(void) {
IntBst *tree = malloc(sizeof *tree);
if (tree == NULL) {
return NULL;
}
tree->root = NULL;
tree->size = 0;
return tree;
}
static void destroy_nodes(BstNode *node) {
if (node == NULL) {
return;
}
destroy_nodes(node->left);
destroy_nodes(node->right);
free(node);
}
void int_bst_destroy(IntBst *tree) {
if (tree == NULL) {
return;
}
destroy_nodes(tree->root);
free(tree);
}
IntBstResult int_bst_insert(
IntBst *tree,
int64_t key,
bool *out_inserted
) {
if (tree == NULL || out_inserted == NULL) {
return INT_BST_INVALID;
}
BstNode **link = &tree->root;
while (*link != NULL) {
if (key == (*link)->key) {
*out_inserted = false;
return INT_BST_OK;
}
link = key < (*link)->key
? &(*link)->left
: &(*link)->right;
}
if (tree->size == SIZE_MAX) {
return INT_BST_INVALID;
}
BstNode *node = malloc(sizeof *node);
if (node == NULL) {
return INT_BST_OUT_OF_MEMORY;
}
node->key = key;
node->left = NULL;
node->right = NULL;
*link = node;
++tree->size;
*out_inserted = true;
return INT_BST_OK;
}
bool int_bst_contains(const IntBst *tree, int64_t key) {
if (tree == NULL) {
return false;
}
const BstNode *node = tree->root;
while (node != NULL) {
if (key == node->key) {
return true;
}
node = key < node->key ? node->left : node->right;
}
return false;
}
static void write_inorder(
const BstNode *node,
int64_t *out_keys,
size_t *cursor
) {
if (node == NULL) {
return;
}
write_inorder(node->left, out_keys, cursor);
out_keys[(*cursor)++] = node->key;
write_inorder(node->right, out_keys, cursor);
}
bool int_bst_inorder(
const IntBst *tree,
int64_t *out_keys,
size_t capacity,
size_t *out_count
) {
if (tree == NULL || out_count == NULL ||
capacity < tree->size ||
(tree->size > 0 && out_keys == NULL)) {
return false;
}
size_t cursor = 0;
write_inorder(tree->root, out_keys, &cursor);
*out_count = cursor;
return true;
}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
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
查找和插入均为