首页 > 代码库 > Splay伸展树
Splay伸展树
伸展树,感觉对我这种菜鸟还是有些吃力,主要也是旋转的时候吧,把要查询的节点旋转到根节点,看网上是有两种方法,一是从上到下,一是从下到上。从上到下,是把树拆分成中树,左树和右树,始终保证目标节点在中树,不断向下把中树的节点添到右树或者左树,直到目标节点为中树的根,再将三树合并起来。另外一种从下到上,旋转操作类似AVL树中的旋转,但是判断好像不是很好写,我写的是从上到下的,另外删除也很巧妙,先把目标节点旋转到根,若此时左子树为空直接删除,否则找到左子树最右的节点当头,利用伸展树的特殊旋转就可以一步删除,太牛叉了,还有就是一个元素和指向它的指针的巧妙运用,真是涨了不少知识啊,,,,
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 typedef struct _spaly 6 { 7 int key; 8 struct _spaly* left; 9 struct _spaly* right; 10 }*Pspaly; 11 12 Pspaly splay(Pspaly tree,int k); 13 void Destory(Pspaly tree); 14 void Printf(Pspaly tree); 15 Pspaly Insert(Pspaly tree,int k); 16 Pspaly Node(int k); 17 Pspaly Delete(Pspaly tree,int k); 18 Pspaly Search(Pspaly tree,int k); 19 20 int main() 21 { 22 Pspaly tree=NULL; 23 tree = Insert(tree,3); 24 tree = Insert(tree,6); 25 tree = Insert(tree,1); 26 tree = Insert(tree,5); 27 tree = Insert(tree,7); 28 tree = Insert(tree,0); 29 tree = Insert(tree,11); 30 Printf(tree); 31 printf("\n"); 32 tree=splay(tree,2); 33 Printf(tree); 34 printf("\n"); 35 // tree = splay(tree,6); 36 tree = Delete(tree,3); 37 Printf(tree); 38 printf("\n"); 39 tree = splay(tree,11); 40 Printf(tree); 41 return 0; 42 } 43 44 Pspaly Node(int k) 45 { 46 Pspaly node = (Pspaly)malloc(sizeof(_spaly)); 47 node->key = k; 48 node->left = NULL; 49 node->right = NULL; 50 return node; 51 } 52 53 Pspaly Insert(Pspaly tree,int k) 54 { 55 Pspaly node = Node(k); 56 if(tree==NULL) 57 { 58 tree = node; 59 return tree; 60 } 61 if(k<tree->key) 62 { 63 tree->left = Insert(tree->left,k); 64 } 65 else if(k>tree->key) 66 { 67 tree->right = Insert(tree->right,k); 68 } 69 return tree; 70 } 71 72 //销毁伸展树 73 void Destory(Pspaly tree) 74 { 75 if(tree==NULL)return; 76 Destory(tree->left); 77 Destory(tree->right); 78 free(tree); 79 } 80 81 //核心,旋转操作 82 Pspaly splay(Pspaly tree,int k) 83 { 84 Pspaly l,r; 85 _spaly N; 86 l = r = &N; // 87 while(true) 88 { 89 if(k<tree->key) 90 { 91 if(tree->left==NULL) 92 break;//当目标节点不在树上时,在删除时有大用 93 if(k<tree->left->key) 94 { 95 Pspaly tem = tree->left; 96 tree->left = tem->right; 97 tem->right = tree; 98 tree = tem; 99 } 100 //将节点加到右树 101 r->left = tree; 102 r = tree; 103 tree = tree->left; 104 } 105 else if(k>tree->key) 106 { 107 if(tree->right==NULL)break; 108 if(k>tree->right->key) 109 { 110 Pspaly tem = tree->right; 111 tree->right = tem->left; 112 tem->left = tree; 113 tree = tem; 114 } 115 l->right = tree; 116 l = tree; 117 tree = tree->right; 118 } 119 else 120 { 121 break; 122 } 123 124 } 125 126 //合并三课树 127 l->right = tree->left; 128 r->left = tree->right; 129 tree->left = N.right; 130 tree->right = N.left; 131 return tree; 132 } 133 134 //打印函数 135 void Printf(Pspaly tree) 136 { 137 if(tree==NULL)return; 138 printf("父亲结点是:%d",tree->key); 139 printf(" 左儿子是:"); 140 if(tree->left==NULL)printf("NULL"); 141 else printf("%d",tree->left->key); 142 printf(" 右儿子是:"); 143 if(tree->right==NULL)printf("NULL\n"); 144 else printf("%d\n",tree->right->key); 145 Printf(tree->left); 146 Printf(tree->right); 147 } 148 149 Pspaly Delete(Pspaly tree,int k) 150 { 151 Pspaly tem; 152 if(Search(tree,k)==NULL) 153 { 154 printf("无\n"); 155 return NULL; 156 } 157 tree = splay(tree,k); 158 if(tree->left==NULL) 159 return tree->right; 160 else 161 { 162 //将tree->left的最右子树当做根 163 tem = splay(tree->left,k); 164 tem->right = tree->right; 165 } 166 free(tree); 167 return tem; 168 } 169 170 Pspaly Search(Pspaly tree,int k) 171 { 172 if(tree==NULL)return NULL; 173 if(k<tree->key)Search(tree->left,k); 174 else if(k>tree->key)Search(tree->right,k); 175 else 176 return tree; 177 }
Splay伸展树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。