日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

伸展树的代码实现

發(fā)布時(shí)間:2023/12/10 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 伸展树的代码实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、伸展樹的數(shù)據(jù)結(jié)構(gòu)

typedef struct Node {int key; struct Node *lch,*rch,*parent; }* Node ,* Tree;

二、伸展樹的基礎(chǔ)操作

下面幾個(gè)函數(shù)中,設(shè)x 的父節(jié)點(diǎn)為 p, p的父節(jié)點(diǎn)為g 。

  • zig( t , x )
    右旋。當(dāng)p是根節(jié)點(diǎn),x是p的左孩子,將x右旋。

    代碼如下:
//單次右旋以 root 節(jié)點(diǎn) 為根節(jié)點(diǎn)的樹 Node zig( Tree tree , Node root) {Node lc = root->lch;Node parent = root->parent;//處理父節(jié)點(diǎn)關(guān)系 if( parent ){if( root == parent->lch ){parent->lch = lc;}else{parent->rch = lc;}lc->parent = parent;}else{lc->parent = NULL;}//翻轉(zhuǎn) if( lc != NULL ){root->lch = lc->rch;if( lc->rch ){lc->rch->parent = root;} lc->rch = root;root->parent = lc;if( parent ){return tree;}else{return lc; }}return tree; }
  • zag( t , x )
    左旋。當(dāng)p是根節(jié)點(diǎn),x是p的右孩子,將x左旋
//單次左旋以 root 節(jié)點(diǎn) 為根節(jié)點(diǎn)的樹 Node zag( Tree tree , Node root) {Node rc = root->rch;Node parent = root->parent;//處理父節(jié)點(diǎn)關(guān)系 if( parent ){if( root == parent->lch ){parent->lch = rc;}else{parent->rch = rc;}rc->parent = parent;}else{rc->parent = NULL;}//翻轉(zhuǎn) if( rc != NULL ){root->rch = rc->lch;if( rc->lch ){rc->lch->parent = root;} rc->lch = root;root->parent = rc;if( parent ){return tree;}else{return rc; }}return tree; }
  • zig_zig( t , x )
    右雙旋。x是p的左節(jié)點(diǎn),當(dāng)p是g的左節(jié)點(diǎn),先將p右旋,再將x右旋
//右雙旋以 root 節(jié)點(diǎn) 為根節(jié)點(diǎn)的樹 Node zig_zig( Tree tree , Node root) {Node lc = root->lch;Node node=zig( tree , root );return zig( node , lc ); }
  • zag_zag( t , x )
    左雙旋。x是p的右節(jié)點(diǎn),當(dāng)p是g的右節(jié)點(diǎn),先將p左旋,再將x左旋
//左雙旋以 root 節(jié)點(diǎn) 為根節(jié)點(diǎn)的樹 Node zag_zag( Tree tree , Node root) {Node rc = root->rch;Node node=zag( tree , root );return zag( node , rc ); }
  • zig_zag( t , x )
    右旋再左旋。x是p的左節(jié)點(diǎn),當(dāng)p是g的右節(jié)點(diǎn),先將x右旋,再將x左旋
Node zig_zag( Tree tree , Node root) {Node node=zig( tree , root->rch );return zag( node , root ); }
  • zag_zig( t , x )
    左旋再右旋。x是p的右節(jié)點(diǎn),當(dāng)p是g的左節(jié)點(diǎn),先將x左旋,再將x右旋
Node zag_zig( Tree tree , Node root) {Node node=zag( tree , root->lch ); return zig( node , root ); }
  • zig_zag_manager( t , x)
    旋轉(zhuǎn)管理者。 找到x,分析x與父親節(jié)點(diǎn),父親節(jié)點(diǎn)與祖父節(jié)點(diǎn)的關(guān)系,選擇恰當(dāng)?shù)男D(zhuǎn)方式。
//根據(jù)目標(biāo)節(jié)點(diǎn)的結(jié)構(gòu)選擇相應(yīng)的算法,策略模式 Node zig_zag_manager( Tree tree , Node node ) { Node parent = node->parent;if( parent == tree ) //1{if( parent->lch == node ){return zig( tree , parent );}else{return zag( tree , parent );}}else if( parent->lch == node ){ //2Node grand = parent->parent; if( grand->lch == parent ){ /*左左*/return zig_zig( tree , grand ); }else{ /*右左*/ return zig_zag( tree , grand );}}else if( parent->rch == node ){ //3Node grand = parent->parent; if( grand->lch == parent ){ /*左右*/return zag_zig( tree , grand ); }else{ /*右右*/return zag_zag( tree , grand );}}return tree; }
  • splay( t ,x )
    將x調(diào)至根部。循環(huán)調(diào)用zig_zag_manager( t , x) 方法,直到x == t
//將目標(biāo)節(jié)點(diǎn)調(diào)整到樹的根部,并返回樹根 Node splay(Tree tree , Node node) {while( node->parent!=NULL ){zig_zag_manager( tree , node );}return node; }
  • find( t , x )
    找到x。找到x,然后將x旋轉(zhuǎn)到樹根。
//尋找key節(jié)點(diǎn) Node find( Tree tree , int key ) {Node curr = tree;while( curr != NULL ){if( curr->key == key ){splay( tree , curr );return curr; } else if( curr->key > key ){curr = curr->lch;}else{curr = curr->rch;}}return NULL; }
  • spilt( t , x)
    以x為界分離t。找到x,將x旋轉(zhuǎn)到樹根,然后將x的左子樹和剩余部分分離
//以 node 為屆,分離 tree 的左子樹 ,返回剩余部分 Node spilt( Tree tree , Node node ) {tree = splay( tree , node ); //將 node 調(diào)至根部Node lc = tree->lch;tree->lch = NULL;if( lc ) {lc->parent = NULL;}return tree; }

注意這里,要獲得左子樹可以在分離之前獲得。

  • join( t1 , t2 )
    合并子樹 t1和t2,要求t1所有元素小于t2的任一元素。找到t1的最大元素,并調(diào)整到根部,將t2作為根的右子樹插入
//合并tree1 和 tree2 ,要求 tree1 所有元素小于 tree2 任一元素 Node join( Tree tree1, Tree tree2) {//找打 tree1 中最大的元素 Node temp = tree1;while( temp->rch != NULL ){temp = temp->rch;} //將 temp調(diào)至 tree1的根部 splay( tree1 ,temp );//將 tree2 作為 temp的右子樹temp->rch = tree2;tree2->parent = temp;return temp; }

附件:
1. C-free工程,也可直接打開文件.zip
2. 廣東工業(yè)大學(xué)-計(jì)算機(jī)學(xué)院-伸展樹.pdf

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的伸展树的代码实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。