伸展樹的學習(四) 在已知的序列中任何位置插入資料

2021-09-03 08:52:42 字數 1977 閱讀 2074

前面講解了伸展樹的原始姿態:二叉搜尋樹!這篇文章呢就講解一下伸展樹的兩種操作:右旋(zag)和左旋(zig)操作:

伸展樹右旋的圖示:

(旋轉的結果就是:使結點t的位置向上移動:人往高處走嘛)

右旋有乙個前提:結點t是結點f的左孩子!根據二叉搜尋樹的性質:各結點滿足以下不等式:

a旋轉後,這個等式也不能變!這樣裡能理解a,b,r結點的掛接情況了

同樣的左旋也也可模擬過來,

伸展樹左旋的圖示:

(旋轉的結果就是:使結點t的位置向根結點移動,也就是使其深度更小:人往高處走嘛)

關於旋轉,有的程式函式名為:zig() zag(),有的直接就稱為:rotate(),其實都是一樣的!沒什麼區別!

簡單的伸展操作了解了,我們看一下poj3580中的要求。

poj3580裡有這樣一種操作要求:insert x p

: insert 

pafter 

ax. for example, performing "

insert

2 4" on results in ,就是在序列的指定位置處插入乙個數!

像這樣的操作用線段樹是很難實現的,但是用伸展樹就很容易了!

比如序列:1 2 3 4 5,我們要在3的後面插入0,使序列變成:1 2 3 0 4 5

#include 

#define inf ~0u>>1

#define mn 200005

#define nil splay

using

namespace std; 

struct splaytree 

node(int _key):key(_key) 

}splay[mn],*sp,*root,*head,*tail; 

////  //對伸展樹進行初始化,也就是把head和tail加入到樹中,

void init() 

//更新結點的值

void update(node *&t) 

//結點t往右旋轉

void zig(node *&t) 

t->right=f,r->father=f,f->father=t,f->left=r; 

update(f);update(t); 

} //結點t往左旋轉

void zag(node *&t) 

t->left=f,ll->father=f,f->father=t,f->right=ll; 

update(f);update(t); 

} //暫時只維護區間,不作伸展操作

void splay(node *&root,node *&t) 

elseelse 

} } 

} //往第pos位後插入key

void insert(int key,int pos) 

if(flag)p->right=t; 

else p->left=t; 

t->father=p; 

splay(root,t); 

} void inorder(node *t) 

}tree; 

//這裡需要注意的是,splaytree一定要定義成全域性變數,不然會因為棧溢位而報記憶體錯誤

int main();//a[0]位置的資料不用

int i; 

//初始化

tree.init(); 

//初始化序列資料

for(i=1;i<5;i++) 

//把0插入到數列的第4個位置

tree.insert(0,4); 

//按下標的順序輸出

tree.inorder(tree.root); 

return 0; } 

程式輸出的結果:2147483647 1 2 3 0 4 5 2147483647 除了head和tail,就正好是我們維護的序列了(head和tail的key值為inf,即0x7fffffff=(2147483647))。

伸展樹的學習(一) 學習的前提

學習伸展樹差不多有兩個多星期了吧!慢慢地也領悟到了它最基本的實現,都不敢說是 初窺門庭!最先看的是楊思雨的 伸展樹的基本操作與應用 現在回頭看確實寫得挺清晰易懂,但是可能是自己看書沒仔細看,或許是悟性太差吧!一直沒看懂,特別是結點旋轉的那幾張圖,即把x旋轉到樹的根結點!後來也不知道是看到哪篇部落格,...

已知樹的中序序列和先序 後序序列,求樹的結構?

已知樹的中序序列和先序 後序序列,求樹的結構?這類問題比較經典了,剛好csdn上有人問起,所以自己寫了乙個遞迴演算法,根據中序和先序 後序 建立樹結構。這裡需要說明的是 必須要知道中序序列,先序和後序可選的情況下才能推導出樹結構,只知道後序先序是推導不出。簡單說明一下基本思路,例 已知後序 debg...

已知前序遍歷序列和中序遍歷序列,求二叉樹的後序遍歷

已知前序遍歷序列和中序遍歷序列,求二叉樹的後序遍歷思路 在前序遍歷的序列中第乙個就是樹的根結點,此時再在中序遍歷的序列裡查詢這個根結點,則中序遍歷的序列里根結點左側的就是左子樹,右側的就是右子樹,再對左右子樹進行同樣的操作,此時可以使用遞迴實現,這樣便能構造出這個二叉樹。class treenode...