使用二叉搜索樹(BST)統計文本中單詞出現頻率。每個節點存儲單詞、計數、左右子樹指針。利用 BST 有序特性,實現 O(log n) 平均查找/插入,最終中序遍歷輸出按字典序排列的統計結果。
#define MAX_WORD_LEN 32
typedef struct BSTNode {
char word[MAX_WORD_LEN];
int count;
struct BSTNode *left;
struct BSTNode *right;
} BSTNode, *BSTree;
word:固定長度字元陣列,避免動態分配碎片count:該單詞出現次數left/right:左右子樹指針,構成遞歸結構cmp_str// 返回 1 若 s < t,0 若 s >= t(簡化兩值邏輯)
int cmp_str(const char *s, const char *t) {
for (int i = 0; s[i] == t[i]; i++)
if (s[i] == '\0') return 0; // 相等
return (s[i] - t[i]) < 0 ? 1 : 0;
}
設計為只返回 0/1,避免 strcmp 的三值(-1,0,1)增加邏輯分支。
str_copyvoid str_copy(char *dest, const char *src) {
while ((*dest++ = *src++) != '\0');
}
解決結構體中字元陣列無法直接賦值(`node->word = val` 非法)的問題。
bst_insertvoid bst_insert(BSTree *root, const char *word) {
if (*root == NULL) {
*root = (BSTree)malloc(sizeof(BSTNode));
str_copy((*root)->word, word);
(*root)->count = 1;
(*root)->left = (*root)->right = NULL;
return;
}
if (cmp_str(word, (*root)->word)) {
bst_insert(&(*root)->left, word); // 更小 → 左子樹
} else if (cmp_str((*root)->word, word)) {
bst_insert(&(*root)->right, word); // 更大 → 右子樹
} else {
(*root)->count++; // 相等 → 計數++
}
}
inorder_printvoid inorder_print(BSTree root) {
if (root) {
inorder_print(root->left);
printf("[%-20s] count: [%d]\n", root->word, root->count);
inorder_print(root->right);
}
}
中序遍歷 BST 產生遞增序列,此處即字典序輸出。
bst_destroyvoid bst_destroy(BSTree root) {
if (root) {
bst_destroy(root->left);
bst_destroy(root->right);
free(root);
}
}
後序遍歷釋放,避免野指針。
int main() {
BSTree root = NULL;
// 硬編碼測試數據(實際可改為文件讀取)
const char *words[] = {"hello", "hey", "hello", "ok", "hey", "hey", "hey"};
int n = sizeof(words) / sizeof(words[0]);
for (int i = 0; i < n; i++) bst_insert(&root, words[i]);
printf("單詞頻率統計(字典序):\n");
inorder_print(root);
bst_destroy(root);
return 0;
}
單詞頻率統計(字典序): [hello ] count: [2] [hey ] count: [4] [ok ] count: [1]
本文展示了從資料結構定義、核心操作封裝、記憶體管理到完整業務流程的標準 C 語言 BST 開發範式。掌握此模板,可快速構建符號表、詞頻統計、路由表等鍵值查找系統。