struct WordNode {
short count; // 詞頻
short len; // 長度
char word[16]; // 單詞 (假設 ≤15 字符)
WordNode *dictPrev; // 字典序雙向鏈表
WordNode *dictNext;
WordNode *countPrev; // 詞頻降序雙向鏈表
WordNode *countNext;
};
維護兩條鏈表:
count++,在詞頻鏈表中向前移動至正確位置。word count。O(N * L) (N=單詞總數, L=平均長度),鏈表操作均為常數級。O(U) (U=唯一單詞數),≤ 10000 節點,極小。WordNode *dictHead = NULL, *dictTail = NULL;
WordNode *countHead = NULL, *countTail = NULL;
WordNode* findOrInsertDict(const char *w) {
WordNode *p = dictHead;
while (p && strcmp(p->word, w) < 0) p = p->dictNext;
if (p && strcmp(p->word, w) == 0) return p; // 找到
// 新建節點
WordNode *node = malloc(sizeof(WordNode));
strcpy(node->word, w);
node->count = 1;
node->len = strlen(w);
// 插入字典序鏈表
if (!p) { // 插到尾部
node->dictPrev = dictTail; node->dictNext = NULL;
if (dictTail) dictTail->dictNext = node; else dictHead = node;
dictTail = node;
} else { // 插到 p 前
node->dictPrev = p->dictPrev; node->dictNext = p;
if (p->dictPrev) p->dictPrev->dictNext = node; else dictHead = node;
p->dictPrev = node;
}
// 掛入詞頻鏈表尾部
node->countPrev = countTail; node->countNext = NULL;
if (countTail) countTail->countNext = node; else countHead = node;
countTail = node;
return node;
}
void bumpCount(WordNode *node) {
node->count++;
// 在詞頻鏈表中向前冒泡
while (node->countPrev && node->count > node->countPrev->count) {
swapCountLinks(node, node->countPrev);
}
}
若單詞量極大 (百萬級),改用 Trie 树 + 堆/桶排序;本題 10000 詞雙向鏈表完全足夠且代碼簡潔。