《演算法導論》第14章 資料結構的擴張 2

2021-08-26 19:43:31 字數 1475 閱讀 1399

在上一節中,我們為樹結點新增size域表示每顆子樹的大小,即包含的結點個數,擴張了

二叉查詢樹為其增加順序統計量的查詢功能。更為自然的想法是直接新增順序統計量rank域

到每個樹結點上。這一節我們就來看下在這樣的設計下,如何擴張來完成上一節相同的功能。

當我們插入乙個結點到二叉樹中,假設它的順序統計量為5,那麼之前二叉樹中順序統計量

大於5的結點都要更新。也就是說插入乙個新結點到對應的位置後,要不斷地查詢其後繼,

完成rank域的更新。所以可以結合習題14.2-1,再新增兩個指標域prev和next指向前趨和後繼,

使查詢前趨和後繼在o(1)內完成。

下面來看具體**。

// 新增三個新域

typedef struct _bstnode bstnode;

// 對於prev和next指標的維護,插入結點分兩種情況:

// 1.新插入結點newnode是其父結點p的左子結點,說明p->prev < newnode < p

// 2.新插入結點newnode是其父結點p的右子結點,說明p < newnode < p->next

//// 對於rank域,如果newnode沒有前趨,那麼rank置為1,否則置為newnode前趨的rank值加1

// 之後開始迭代更新,將newnode的所有後繼的rank值都加1。

void bst_insert(bstnode **root, bstnode *newnode)

// link newnode to pnode

newnode->parent = pnode;

// link pnode to newnode

// 新邏輯:維護prev, next

if (pnode == null) else if (newnode->key < pnode->key)

else

// 新邏輯:維護rank域

if (newnode->prev == null)

newnode->rank = 1;

else

newnode->rank = newnode->prev->rank + 1;

bstnode *succesor = newnode;

while ((succesor = succesor->next) != null)

}// select和rank操作變得格外簡單

bstnode *bst_os_select(bstnode *node, int i)

return null;

}int bst_os_rank(bstnode *node)

通過這一節和上一節的對比,可以看出在步驟(2)中對基礎資料結構新增不同的域,會對

步驟(3)和(4)改寫和新增新的操作產生很大影響。因此,在擴張資料結構時可以採用

試錯法,嘗試新增不同的域,權衡各種方案的優劣。

資料結構的擴張 演算法導論第14章(194)

偽 解釋 為明白os select是如何操作的,在上圖所示的順序統計圖上查詢第17小元素的查詢過程。以x為根開始,其關鍵字為26。i 17.因為在26的左子樹大小為12,故他的秩為13,因此,秩為17的節點是26的右子樹第17 13 4小得瑟元素。遞迴呼叫後,x為關鍵字41的節點,i 4,因為41的...

演算法導論筆記 14資料結構的擴張

一 概述 一些工程應用只會使用教科書式的標準資料結構,但是也會有些應用需要對現有的資料結構進行少許的創新和改造,只有很少的情況會創造全新的資料結構。二 動態順序統計 順序統計 n個元素中第i個順序統計量,就是具有第i小關鍵字的元素。對於乙個無序的集合,可以在 o n 的時間內得到任意的順序統計量。利...

《演算法導論》讀書筆記之第14章 資料結構的擴張

前言 通常我們會遇到一些問題,採用一些標準的資料結構,如雙鏈表 雜湊表或二叉查詢數時,不能夠滿足操作要求,需要對這些資料結構進行擴張,新增一些額外的資訊使得能夠完成新的操作。附加的資訊需要對資料結構的某些操作進行調整,這個是非常關鍵的步驟,決定著資料結構擴張是否能夠實現。本章主要討論了紅黑樹結構的擴...