系統需求
- 單詞錄入/新增
- 單詞刪除(含重複單詞處理)
- 瀏覽/列印所有單詞
- A-Z 字母順序排序
資料結構設計
typedef struct WordNode {
int id; // 流水號
char word[50]; // 單詞(支援較長單詞)
char meaning[200]; // 中文釋義
struct WordNode *next; // 指向下一節點
} WordNode;
核心功能實作
1. 建立空字典(頭節點)
WordNode* dict_create() {
WordNode *head = (WordNode*)malloc(sizeof(WordNode));
if (!head) return NULL;
head->id = 0;
head->word[0] = '\0';
head->meaning[0] = '\0';
head->next = NULL;
return head;
}
2. 插入單詞(按字母序插入,自動排序)
int dict_insert(WordNode *head, const char *word, const char *meaning) {
if (!head || !word) return -1;
// 檢查重複
WordNode *curr = head->next;
while (curr) {
if (strcmp(curr->word, word) == 0) {
printf("單詞 \"%s\" 已存在!\n", word);
return 0; // 重複,不插入
}
curr = curr->next;
}
// 找到插入位置(維持字母序)
WordNode *pre = head;
WordNode *curr = head->next;
while (curr && strcmp(curr->word, word) < 0) {
pre = curr;
curr = curr->next;
}
// 建立新節點
WordNode *new_node = (WordNode*)malloc(sizeof(WordNode));
if (!new_node) return -1;
static int global_id = 1;
new_node->id = global_id++;
strcpy(new_node->word, word);
strcpy(new_node->meaning, meaning ? meaning : "");
new_node->next = curr;
pre->next = new_node;
return 1; // 成功
}
3. 刪除單詞
int dict_delete(WordNode *head, const char *word) {
if (!head || !word) return -1;
WordNode *pre = head;
WordNode *curr = head->next;
while (curr) {
if (strcmp(curr->word, word) == 0) {
pre->next = curr->next;
free(curr);
return 1; // 刪除成功
}
pre = curr;
curr = curr->next;
}
return 0; // 找不到
}
4. 瀏覽/列印所有單詞
void dict_print(WordNode *head) {
if (!head) return;
WordNode *curr = head->next;
printf("%-5s %-20s %s\n", "ID", "單詞", "釋義");
printf("------------------------------------------------\n");
while (curr) {
printf("%-5d %-20s %s\n", curr->id, curr->word, curr->meaning);
curr = curr->next;
}
}
5. 查詢單詞
WordNode* dict_search(WordNode *head, const char *word) {
if (!head || !word) return NULL;
WordNode *curr = head->next;
while (curr) {
if (strcmp(curr->word, word) == 0)
return curr;
curr = curr->next;
}
return NULL;
}
6. 排序功能(鏈結串列氣泡排序,交換資料而非節點)
void dict_sort(WordNode *head) {
if (!head || !head->next || !head->next->next) return; // 0或1個節點無需排序
int swapped;
WordNode *ptr1;
WordNode *lptr = NULL;
do {
swapped = 0;
ptr1 = head->next;
while (ptr1->next != lptr) {
if (strcmp(ptr1->word, ptr1->next->word) > 0) {
// 交換節點資料(id 不交換,保持原始錄入順序編號)
char temp_word[50], temp_meaning[200];
strcpy(temp_word, ptr1->word);
strcpy(temp_meaning, ptr1->meaning);
strcpy(ptr1->word, ptr1->next->word);
strcpy(ptr1->meaning, ptr1->next->meaning);
strcpy(ptr1->next->word, temp_word);
strcpy(ptr1->next->meaning, temp_meaning);
swapped = 1;
}
ptr1 = ptr1->next;
}
lptr = ptr1;
} while (swapped);
}
主程式選單整合
int main() {
WordNode *dict = dict_create();
if (!dict) {
fprintf(stderr, "記憶體配置失敗\n");
return 1;
}
int choice;
char word[50], meaning[200];
while (1) {
printf("\n=== 英文字典系統 ===\n");
printf("1. 新增單詞\n2. 刪除單詞\n3. 瀏覽所有\n4. 查詢單詞\n5. 重新排序\n0. 結束\n");
printf("請選擇:");
if (scanf("%d", &choice) != 1) break;
switch (choice) {
case 1:
printf("輸入單詞:"); scanf("%s", word);
printf("輸入釋義:"); scanf(" %[^\n]", meaning); // 讀取含空格的釋義
dict_insert(dict, word, meaning);
break;
case 2:
printf("輸入要刪除的單詞:"); scanf("%s", word);
if (dict_delete(dict, word)) printf("刪除成功\n");
else printf("找不到該單詞\n");
break;
case 3:
dict_print(dict);
break;
case 4:
printf("輸入查詢單詞:"); scanf("%s", word);
WordNode *found = dict_search(dict, word);
if (found) printf("找到:%s - %s\n", found->word, found->meaning);
else printf("未找到\n");
break;
case 5:
dict_sort(dict);
printf("排序完成\n");
break;
case 0:
printf("再見!\n");
// 釋放所有記憶體
WordNode *curr = dict->next;
while (curr) {
WordNode *tmp = curr;
curr = curr->next;
free(tmp);
}
free(dict);
return 0;
default:
printf("無效選項\n");
}
}
return 0;
}
關鍵技術點總結
| 技術點 | 說明 |
| 虛擬頭節點 | 簡化插入/刪除邏輯,統一處理頭節點特殊情況 |
| 字串處理 | 使用 strcpy、strcmp、scanf("%[^\n]") 讀取含空格字串 |
| 記憶體管理 | 每個 malloc 對應 free,程式結束前釋放整串鏈結 |
| 插入即排序 | 新增時直接找正確位置插入,避免事後排序開銷 |
| 鏈結串列排序 | 交換節點資料而非指標,較簡單但需注意 id 不交換 |
進階擴充建議
- 檔案存取:
fwrite/fread 實作字典持久化
- 雙向鏈結串列:支援反向瀏覽、更高效刪除
- 雜湊表/Trie 樹:大量單詞時提升查詢速度至 O(1)/O(L)
- 圖形介面:搭配 ncurses 或 GUI 函式庫