1、二分尋找與二叉樹:效率、空間、靈活性的權衡
資料與鏈表的互補:
數組: 尋找快(使用二分叉找)->log2N 。插入和刪除極為不便。->移動其它資料的開銷。要保持資料有序,則必然有大量的插入刪除操作。
鏈表: 為每個元素帶上兩個指標,分別指向其前結點和後結點。
1)打破了資料對空間相關性的依賴。避免了插入刪除時移動資料的開銷。
2)不能使用二分尋找。
為了能在鏈表中使用二分叉找,我們將元素的指標做一些改變:不再指向其前後元素。而指向其二分結點元素。
其資料結構定義如下:template <class Entry>
struct Binary_node
{
Entry data;
Binary_node<Entry> *left;
Binary_node<Entry> *right;
}
插入和刪除引起了二叉樹的不平衡。
我們將數組的範圍擴大到 1-24,而且經過刪除操作,只剩下了如的7個元素:
任何的不平衡,可以通過兩種旋轉操作來完成:左旋轉、右旋轉。
調整三個結點的關係: 孫子結點、父結點、爺爺結點。
修改三個指標值:指向爺爺結點的指標(當前根結點)、指向父結點的指標、指向叔父結點的指標。
template <class Record>
Error_code Search_tree<Record> :: rotate_right( Binary_node<Record> * ¤t )
{
Binary_node<Record>* reg = current->left;
current->left = reg->right;
reg->right = current;
// 正確地指向當前根結點
current = reg;
return okay;
}
template <class Record>
RB_code Search_tree<Record> :: rotate_left(Binary_node<Record> * ¤t )
{
Binary_node<Record>* reg = current->right;
current->right = reg->left;
reg->left = current;
// 正確地指向當前根結點
current = reg;
return okay;
}
Error_code Search_tree<Record> ::double_rotate_left(Binary_node<Record> * ¤t )
{
rotate_right( current );
rotate_left( current );
return okay;
}
template <class Record>
Error_code Search_tree<Record> :: double_rotate_right(Binary_node<Record> * ¤t )
{
rotate_left( current );
rotate_right( current );
return okay;
}
紅/黑樹狀結構--懶漢平衡
紅/黑樹狀結構 vs 平衡二叉樹
1)效能幾乎沒有下降
2)減少了開銷
基本思想:從根結點開始,層與層紅黑相間。直有兩層黑的相遇,才旋轉。
紅/黑樹狀結構的基本操作:
1)著色:flip_color()
2) 旋轉:借用 search-tree 的方法。
紅/黑樹狀結構結點的四種狀態:enum RB_code { okay, red_node, left_red, right_red };
okey: 合法的紅/黑樹狀結構。
red_node: 樹結構平衡,根結點顏色為紅。
left_red: 樹結構不平衡,左子結點為紅。
right_red:樹結構不平衡,右子結點為紅。
紅/黑樹狀結構的葉子結點:概念上存在而物理上不存在。
最壞情況:
插入操作:
刪除操作:
應用:
多數應用中,結點還包含一個父結點:// Linux-2.6.17/include/linux/rbtree.h
struct rb_node
{
unsigned long rb_parent_color;
#define RB_RED 0
#define RB_BLACK 1
struct rb_node *rb_right;
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
/* The alignment might seem pointless, but allegedly CRIS needs it */
// stl/stl_tree.h
struct _Rb_tree_node_base
{
typedef _Rb_tree_Color_type _Color_type;
typedef _Rb_tree_node_base* _Base_ptr;
_Color_type _M_color;
_Base_ptr _M_parent;
_Base_ptr _M_left;
_Base_ptr _M_right;
};
template <class _Value>
struct _Rb_tree_node : public _Rb_tree_node_base
{
typedef _Rb_tree_node<_Value>* _Link_type;
_Value _M_value_field;
};
fdfd
Referance
《data_structures and program design in cpp》