高级数据结构实现——自顶向下伸展树
生活随笔
收集整理的這篇文章主要介紹了
高级数据结构实现——自顶向下伸展树
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README
1) 本文部分內容轉自 數據結構與算法分析,旨在理解 高級數據結構實現——自頂向下伸展樹 的基礎知識;
2) 源代碼部分思想借鑒了數據結構與算法分析,有一點干貨原創代碼,for original source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter12/p345_topdown_splay_tree
3) you can also refer to the link http://www.cnblogs.com/huangxincheng/archive/2012/08/04/2623455.html
4) for basic splay tree , please visit http://blog.csdn.net/PacosonSWJTU/article/details/50525435
【1】自頂向下伸展樹相關
1)problem+solution
- 1.1)problem: 普通伸展樹的展開操作需要從根沿樹往下的一次遍歷, 以及而后的從底向上的一次遍歷。(詳情,參見: http://blog.csdn.net/pacosonswjtu/article/details/50525435) 這可以通過保存一些父指針來完成, 或者通過將訪問路徑存儲到一個棧中來完成。 但遺憾的 是, 這兩種方法均需要大量的開銷 ;
- 1.2)solution: 本節中, 我們指出如何在初始訪問路徑上施行一些旋轉。結果得到在時間中更快的過程,只用到 O(1)的額外空間, 但卻保持了 O(logN) 的攤還時間界;(干貨——伸展樹是基于AVL樹的, 在AVL的基礎上引入伸展樹的目的是保持他的攤還時間界為 O(logN))
2)對伸展樹的自頂向下的旋轉操作:(單旋轉+一字型旋轉+之字型旋轉)
- 2.1)這種伸展方式會把樹切成三份,L樹,M樹,R樹,考慮的情況有:單旋轉,“一字型”旋轉,“之字形”旋轉。起初左樹(L) 和 右樹(R)均為空(NULL);
3)看個荔枝:
- 3.1)splay + deleting opeartions:
- 3.2)inserting opeartions:
4)source code at a glance
#include "topdown_splay_tree.h" // allocate memory for new node. Node makeNode(int value) {Node node;node = (Node)malloc(sizeof(struct Node));if(!node){Error("failed makeNode, for out of space !");return NULL;}node->left = NULL;node->right = NULL; node->value = value;return node; }// left left single rotate TopDownSplayTree left_left_single_rotate(TopDownSplayTree root) { TopDownSplayTree temp;temp = root; // 1st steproot = root->left; // 2nd steptemp->left = root->right; // 3rd steproot->right = temp; // 4th stepreturn root; }// right_right_single_rotate TopDownSplayTree right_right_single_rotate(TopDownSplayTree root) { TopDownSplayTree temp;temp = root; // 1st steproot = root->right; // 2nd steptemp->right = root->left; // 3rd steproot->left = temp; // 4th step return root; }// performing splay operations TopDownSplayTree topdown_splay(int value, TopDownSplayTree middle) {struct Node plusTree; Node leftTreeMax; Node rightTreeMin;leftTreeMax = &plusTree;rightTreeMin = &plusTree;while(value != middle->value){ if(middle->value < value) // the new node is greater.{ if(middle->right == NULL){break;}else if(middle->right->value < value && middle->right->right){middle = right_right_single_rotate(middle);} leftTreeMax->right = middle;leftTreeMax = middle;middle = middle->right; leftTreeMax->right = NULL;}if(middle->value > value) // the new node is less.{ if(middle->left == NULL){break;}else if(middle->left->value > value && middle->left->left){middle = left_left_single_rotate(middle);}rightTreeMin->left = middle;rightTreeMin = middle;middle = middle->left;rightTreeMin->left = NULL;} }leftTreeMax->right = middle->left;rightTreeMin->left = middle->right;middle->left = plusTree.right;middle->right = plusTree.left;return middle; }// delete the root of the TopDownSplayTree TopDownSplayTree deleteNode(int value, TopDownSplayTree root) {TopDownSplayTree newroot;if(root == NULL) {return root;}else // the splay tree is not null{root = topdown_splay(value, root);if(root->value == value) // find the node with given value.{ if(root->left == NULL){newroot = root->right;}else{newroot = root->left;// perform splay again with value towards the left subtree which is not null.newroot = topdown_splay(value, newroot);newroot->right = root->right; }free(root);root = newroot;} } return root; }// insert the node with value into the TopDownSplayTree TopDownSplayTree insert(int value, TopDownSplayTree root) {TopDownSplayTree node;node = makeNode(value); if(root == NULL) // the splay tree is null{return node;}else // the splay tree is not null{root = topdown_splay(value, root);if(root->value > value) {node->left = root->left;node->right = root;root->left = NULL;root = node; }else if(root->value < value) {node->right = root->right;root->right = NULL;node->left = root; root = node;}else {return root;}} return root; }// test for insert operation. int main1() {TopDownSplayTree root; int data[] = {5, 11, 23, 10, 17};int size = 5;int i;printf("\n === executing insert with {5, 11, 23, 10, 17} in turn.=== \n");root = NULL;for(i=0; i<size; i++){root = insert(data[i], root);printPreorder(1, root); } printf("\n === executing insert with 8 in turn.=== \n");root = insert(8, root);printPreorder(1, root); printf("\n === executing insert with 18 in turn.=== \n");root = insert(18, root);printPreorder(1, root);return 0; }// test for splay operation and deleting operation. int main() { TopDownSplayTree root;TopDownSplayTree temp;printf("\n ====== test for splaying operation====== \n");printf("\n === original tree is as follows.=== \n");root = makeNode(12); // root = 12temp = root;temp->left = makeNode(5);temp->right = makeNode(25);temp = temp->right; // root = 25temp->left = makeNode(20);temp->right = makeNode(30);temp = temp->left; // root = 20temp->left = makeNode(15);temp->right = makeNode(24);temp = temp->left; // root = 15temp->left = makeNode(13);temp->right = makeNode(18);temp = temp->right; // root = 18temp->left = makeNode(16); printPreorder(1, root);printf("\n === executing splay operation with finding value=19.=== \n");root = topdown_splay(19, root);printPreorder(1, root); printf("\n === executing deleting operation with value=15.=== \n");root = deleteNode(15, root);printPreorder(1, root); return 0; }// analog print node values in the binominal tree, which involves preorder traversal. void printPreorder(int depth, TopDownSplayTree root) { int i;if(root) { for(i = 0; i < depth; i++)printf(" ");printf("%d\n", root->value); printPreorder(depth + 1, root->left); printPreorder(depth + 1, root->right);} else{for(i = 0; i < depth; i++)printf(" ");printf("NULL\n");} }總結
以上是生活随笔為你收集整理的高级数据结构实现——自顶向下伸展树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见 Java 字节码 指令 助记符
- 下一篇: 大太监大结局 大太监的结局是什么