构建伸展树的伸展操作

以下结果与书中描述略有出入,因为书中没有给出代码示例,因此只能认为本人的结果与书中描述的现象大致相似;

主要的函数:查找函数(同时伸展):

  1 ETree *findNode(ETree *&root,const int &data)
  2 {
  3     ETree *tmp;
  4     ETree *k1, *k2, *k3;
  5     if (root == nullptr)
  6         return root;
  7
  8     //三种主要情况
  9     if (root->data == data)
 10         return root;
 11     else if (root->data > data)
 12     {//在左子树的情况
 13         if (root->left == nullptr)
 14             return nullptr;
 15         if (root->left->data == data)
 16         {
 17             tmp = root->left;
 18             root->left = tmp->right;
 19             tmp->right = root;
 20             root = tmp;//将查到的节点转移到当前根节点
 21         }
 22         else if (root->left->data > data)
 23         {//在左儿子的左子树
 24             if (root->left->left == nullptr)
 25                 return nullptr;
 26             if (root->left->left->data == data)
 27             {
 28                 k1 = root;
 29                 k2 = root->left;
 30                 k3 = k2->left;
 31                 k1->left = k2->right;
 32                 k2->right = k1;
 33                 k2->left = k3->right;
 34                 k3->right = k2;
 35                 root = k3;
 36             }
 37             else
 38             {
 39                 root->left->left = findNode(root->left->left, data);//这里是实现的重点
 40                 root = findNode(root, data);
 41             }
 42         }
 43         else
 44         {
 45             if (root->left->right == nullptr)
 46                 return nullptr;
 47             if (root->left->right->data == data)
 48             {
 49                 k1 = root;
 50                 k2 = root->left;
 51                 k3 = k2->right;
 52                 k1->left = k3->right;
 53                 k2->right = k3->left;
 54                 k3->left = k2;
 55                 k3->right = k1;
 56                 root = k3;
 57             }
 58             else
 59             {
 60                 root->left->right = findNode(root->left->right, data);
 61                 root = findNode(root, data);
 62             }
 63         }
 64     }
 65     else
 66     {
 67         if (root->right == nullptr)
 68             return nullptr;
 69
 70         if (root->right->data == data)
 71         {
 72             tmp = root->right;
 73             root->right = tmp->left;
 74             tmp->left = root;
 75             root = tmp;
 76         }
 77         else if (root->right->data < data)
 78         {
 79             if (root->right->right == nullptr)
 80                 return nullptr;
 81
 82             if (root->right->right->data == data)
 83             {
 84                 k1 = root;
 85                 k2 = root->right;
 86                 k3 = k2->right;
 87                 k1->right = k2->left;
 88                 k2->left = k1;
 89                 k2->right = k3->left;
 90                 k3->left = k2;
 91                 root = k3;
 92             }
 93             else
 94             {
 95                 root->right->right = findNode(root->right->right, data);
 96                 root = findNode(root, data);
 97             }
 98         }
 99         else
100         {
101             if (root->right->left == nullptr)
102                 return nullptr;
103             if (root->right->left->data == data)
104             {
105                 k1 = root;
106                 k2 = root->right;
107                 k3 = k2->left;
108                 k1->right = k3->left;
109                 k2->left = k3->right;
110                 k3->left = k1;
111                 k3->right = k2;
112                 root = k3;
113             }
114             else
115             {
116                 root->right->left = findNode(root->right->left, data);
117                 root = findNode(root, data);
118             }
119         }
120     }
121
122     return root;
123 }

函数分别为两种情况进行了操作,分别是对称的,其中递归调用的部分是我出错最多的地方;

总体结果与书中类似,但是由于我是间隔进行查询的,因此与书中有差异;应当不影响结果:

全部代码如下:

  1 #include <iostream>
  2 using namespace std;
  3
  4 typedef struct _extTree_
  5 {
  6     int data;
  7     struct _extTree_ *left;
  8     struct _extTree_ *right;
  9 }ETree;
 10
 11 ETree *insertNode(ETree *root,const int &data)
 12 {
 13     if (root == nullptr)
 14     {
 15         root = new ETree;
 16         root->left = nullptr;
 17         root->right = nullptr;
 18         root->data = data;
 19     }
 20     else if (root->data > data)
 21         root->left = insertNode(root->left, data);
 22     else if (root->data < data)
 23         root->right = insertNode(root->right, data);
 24     return root;
 25 }
 26
 27 ETree *findNode(ETree *&root,const int &data)
 28 {
 29     ETree *tmp;
 30     ETree *k1, *k2, *k3;
 31     if (root == nullptr)
 32         return root;
 33
 34     //三种主要情况
 35     if (root->data == data)
 36         return root;
 37     else if (root->data > data)
 38     {//在左子树的情况
 39         if (root->left == nullptr)
 40             return nullptr;
 41         if (root->left->data == data)
 42         {
 43             tmp = root->left;
 44             root->left = tmp->right;
 45             tmp->right = root;
 46             root = tmp;//将查到的节点转移到当前根节点
 47         }
 48         else if (root->left->data > data)
 49         {//在左儿子的左子树
 50             if (root->left->left == nullptr)
 51                 return nullptr;
 52             if (root->left->left->data == data)
 53             {
 54                 k1 = root;
 55                 k2 = root->left;
 56                 k3 = k2->left;
 57                 k1->left = k2->right;
 58                 k2->right = k1;
 59                 k2->left = k3->right;
 60                 k3->right = k2;
 61                 root = k3;
 62             }
 63             else
 64             {
 65                 root->left->left = findNode(root->left->left, data);//这里是实现的重点
 66                 root = findNode(root, data);
 67             }
 68         }
 69         else
 70         {
 71             if (root->left->right == nullptr)
 72                 return nullptr;
 73             if (root->left->right->data == data)
 74             {
 75                 k1 = root;
 76                 k2 = root->left;
 77                 k3 = k2->right;
 78                 k1->left = k3->right;
 79                 k2->right = k3->left;
 80                 k3->left = k2;
 81                 k3->right = k1;
 82                 root = k3;
 83             }
 84             else
 85             {
 86                 root->left->right = findNode(root->left->right, data);
 87                 root = findNode(root, data);
 88             }
 89         }
 90     }
 91     else
 92     {
 93         if (root->right == nullptr)
 94             return nullptr;
 95
 96         if (root->right->data == data)
 97         {
 98             tmp = root->right;
 99             root->right = tmp->left;
100             tmp->left = root;
101             root = tmp;
102         }
103         else if (root->right->data < data)
104         {
105             if (root->right->right == nullptr)
106                 return nullptr;
107
108             if (root->right->right->data == data)
109             {
110                 k1 = root;
111                 k2 = root->right;
112                 k3 = k2->right;
113                 k1->right = k2->left;
114                 k2->left = k1;
115                 k2->right = k3->left;
116                 k3->left = k2;
117                 root = k3;
118             }
119             else
120             {
121                 root->right->right = findNode(root->right->right, data);
122                 root = findNode(root, data);
123             }
124         }
125         else
126         {
127             if (root->right->left == nullptr)
128                 return nullptr;
129             if (root->right->left->data == data)
130             {
131                 k1 = root;
132                 k2 = root->right;
133                 k3 = k2->left;
134                 k1->right = k3->left;
135                 k2->left = k3->right;
136                 k3->left = k1;
137                 k3->right = k2;
138                 root = k3;
139             }
140             else
141             {
142                 root->right->left = findNode(root->right->left, data);
143                 root = findNode(root, data);
144             }
145         }
146     }
147
148     return root;
149 }
150
151 void deleteTree(ETree *&root)
152 {
153     if (root == nullptr)
154         return;
155     if (root->left != nullptr)
156         deleteTree(root->left);
157     if (root->right != nullptr)
158         deleteTree(root->right);
159     delete root;
160     root = nullptr;
161 }
162
163 int main(void)
164 {
165     ETree *root = nullptr;
166     ETree *test = nullptr;
167     int i = 32;
168     while (i > 0)
169     {
170         root = insertNode(root, i);
171         --i;
172     }
173     test = findNode(root, 1);
174     test = findNode(root, 2);
175     test = findNode(root, 3);
176     deleteTree(root);
177     system("pause");
178     return 0;
179 }

伸展树相关可以自行查阅介绍资料;

以上。

时间: 2024-10-12 04:01:07

构建伸展树的伸展操作的相关文章

Splay伸展树入门(单点操作,区间维护)

ps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是一颗二叉搜索树,刚刚开始学的时候找题hash数字的题先测板子... 后来那题被学长改了数据不能用平衡树测了...一道二分数字的题. 二叉搜索树的功能是,插入一个数字,在O(logn)的时间内找到它,并操作,插入删除等.但是可能会让二叉搜索树退化成链,复杂度达到O(n) 原文地址:https://www.c

查找——清晰图解伸展树SplayTree

伸展树 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它由Daniel Sleator和Robert Tarjan创造,后者对其进行了改进. 假设想要对一个二叉查找树执行一系列的查找操作.为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置.于是想到设计一个简单方法,在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方.splaytree应运而生.splaytree是一种自调整形式的二叉查找树,它会沿着从某个节点到树根之间的路径,通过一系列的旋转

数据结构-伸展树

声明:本文是对某高中生的竞赛论文学习的文章 介绍: 二叉查找树能够支持多种动态集合操作.对于一个含有n个结点的完全二叉树,这些操作的最还情况运行时间是O(lgn),但如果树是含有n个结点的线性链,则这些操作的最坏情况运行时间为O(n).而像红黑树.AVL树这种二叉查找树的变形在最坏情况下,仍能保持较好性能. 本文将要介绍的伸展树也是二叉查找树的变形,它对空间要求及编程难度的要求相对不高. 伸展树: 伸展树与二叉查找树一样,具有有序性.即伸展树的每一个结点x满足:该结点的左子树中的每个元素都小于x

《树》之伸展树

本文介绍什么? 使用伸展树有什么样的效果: 伸展树的定义: 伸展树ADT具体实现过程的描述: 代码实现. 一.使用伸展树(splay tree)的效果: 使用伸展树时,对伸展树上任意一次操作的最坏运行时间为 O( N ):但是,它保证了连续M次操作花费的最多时间为O(M ㏒N),从而可以推算出对伸展树的每一次操作的摊还时间为O( ㏒N). 二.伸展树的定义: 对于一颗二查查找树进行操作时,每访问一个节点,该节点都通过旋转操作被放到根上.这样的一颗二查查找树称为伸展树. 三.伸展树ADT的描述:

高级数据结构实现——自顶向下伸展树

[0]README 1) 本文部分内容转自 数据结构与算法分析,旨在理解 高级数据结构实现——自顶向下伸展树 的基础知识: 2) 源代码部分思想借鉴了数据结构与算法分析,有一点干货原创代码,for original source code, please visithttps://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter12/p345_topdown_splay_tree 3) you c

poj_3580 伸展树

自己伸展树做的第一个题 poj 3580 supermemo. 题目大意 对一个数组进行维护,包含如下几个操作: ADD x, y, d 在 A[x]--A[y] 中的每个数都增加d REVERSE x, y 将 A[x]--A[y] 中的数进行反转,变为 A[y],A[y-1]....A[x+1],A[x] REVOLVE x, y, T 将 A[x]--A[y]中的数连续右移T次 INSERT x, P 在A后添加数P DELETE x 删除A[x] MIN x, y 查询A[x]--A[y

自顶向下的伸展树

一 伸展树的性质 伸展树保证从控制开始任意连续M次对树的操作最多花费O(MlogN)时间,一棵伸展树每次操作的摊还(amortized)代价是O(logN).伸展树的基本思想是,当一个节点被访问后,它就要经过一系列旋转操作被推到根上.另外,伸展树还不要求保留高度或平衡信息. 二 伸展树的伸展操作 在自底向上的伸展操作的直接实现需要从根沿树往下的一次遍历,以及而后的自底向上的一次遍历.这可以通过保存一些父链来完成,也可以通过将访问路径存储到栈中来完成.但是,这两种方法均需大量的开销,而且两者都必须

树-伸展树(Splay Tree)

伸展树概念 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由Daniel Sleator和Robert Tarjan创造. (01) 伸展树属于二叉查找树,即它具有和二叉查找树一样的性质:假设x为树中的任意一个结点,x节点包含关键字key,节点x的key值记为key[x].如果y是x的左子树中的一个结点,则key[y] <= key[x]:如果y是x的右子树的一个结点,则key[y] >= key[x]. (02) 除了拥有二叉查找树的性质

伸展树基本概念基本题目

http://blog.csdn.net/discreeter/article/details/51524210   //基本概念详见这里 例题HDU4453 代码来源http://blog.csdn.net/auto_ac/article/details/12318809 伸展树我个人理解就是每次查询或更改都要将其移动至根节点 另外伸展树有单点操作和区间操作 维护的是一个中序遍历(这点很重要) 旋转操作的话结合概念和代码还是很清晰的,有左旋(当要进行旋转操作的是其根节点的右节点),右旋(当要进