C++ Splay树实现
我正在尝试实现一个splay树。但是splay()函数调用的left_rotate和right_rotate函数中出现了一个分段错误。我试过调试,但没有任何线索。我哪里做错了! 我认为有某种逻辑错误。 这是我的密码: 八字树C++ Splay树实现,c++,binary-tree,binary-search-tree,splay-tree,C++,Binary Tree,Binary Search Tree,Splay Tree,我正在尝试实现一个splay树。但是splay()函数调用的left_rotate和right_rotate函数中出现了一个分段错误。我试过调试,但没有任何线索。我哪里做错了! 我认为有某种逻辑错误。 这是我的密码: 八字树 #包括“node.h” 模板 类八字树{ 私人: Node*root=nullptr; 公众: 八字树(){ root=nullptr; } //gethead 节点*gethead(){ 返回此->根目录; } 无效左旋转(节点*节点){ 如果(node==nullptr
#包括“node.h”
模板
类八字树{
私人:
Node*root=nullptr;
公众:
八字树(){
root=nullptr;
}
//gethead
节点*gethead(){
返回此->根目录;
}
无效左旋转(节点*节点){
如果(node==nullptr){return;}
如果(node->m_right!=nullptr){
Node*temp=Node->m_right;
节点->m_right=temp->m_left;
如果(临时->m_左){
temp->m_left->m_parent=节点;
}
temp->m_parent=节点->m_parent;
if(node->m_parent==nullptr){
这个->根=温度;
}else if(node=node->m_parent->m_left){
节点->母节点->左节点=临时节点;
}else if(node=node->m_parent->m_right){
节点->主节点->主节点->右节点=临时节点;
}
temp->m_left=节点;
节点->m_父节点=临时;
}
}
//右转
无效右旋转(节点*节点){
Node*temp=Node->m_left;
节点->左m_=临时->右m_;
如果(临时->m_右){
temp->m_right->m_parent=节点;
}
temp->m_parent=节点->m_parent;
if(node->m_parent==nullptr){
这个->根=温度;
}else if(节点==节点->m_父节点->m_左){
节点->母节点->左节点=临时节点;
}否则{
节点->主节点->主节点->右节点=临时节点;
}
temp->m_right=节点;
节点->m_父节点=临时;
}
//展开节点
空心八字形(节点*节点){
while(节点->m_父节点){
如果(节点->m_父节点->m_父节点==nullptr){
如果(节点==节点->m_父节点->m_左){
右旋转(节点->主节点);
}else if(节点==节点->m_父节点->m_右){
左旋转(节点->主节点);
}
}else if(节点->m_父节点->m_父节点!=nullptr){
if(node==node->m_parent->m_left&&node->m_parent==node->m_parent->m_parent->m_left){
右旋转(节点->主节点->主节点);
右旋转(节点->主节点);
}否则,如果(节点==节点->m_父节点->m_右&&node->m_父节点==节点->m_父节点->m_父节点->m_右){
左旋转(节点->主节点->主节点);
左旋转(节点->主节点);
}否则,如果(节点==节点->m_父节点->m_右和&节点->m_父节点==节点->m_父节点->m_父节点->m_左){
右旋转(节点->主节点);
左旋转(节点->主节点);
}否则{
左旋转(节点->主节点);
右旋转(节点->主节点);
}
}
}
}
无效插入(T数据){
插入(数据,此->根);
}
节点*插入(T数据,节点*节点){
if(this->root==nullptr){
此->根=新节点(数据);
返回此->根目录;
}else{Node*curr_ptr=Node;
while(节点!=nullptr){
if(数据管理单元数据){
如果(节点->左m_!=nullptr){
节点->左m_=插入(数据,节点->左m_);
}否则{
节点*新节点=新节点(数据);
curr\u ptr->m\u left=新建\u节点;
新建节点->主节点=curr\u ptr;
splay(新的_节点);
}
}else if(数据>节点->m_数据){
if(node->m_right!=nullptr){
节点->鼠标右键=插入(数据,节点->鼠标右键);
}否则{
节点*新节点=新节点(数据);
curr\u ptr->m\u right=新建\u节点;
新建节点->主节点=curr\u ptr;
splay(新的_节点);
}
}
}
}
返回节点;
}
};
node.h
模板
类节点{
公众:
T m_data;//持有密钥
Node*m_parent;//指向父节点的指针
Node*m_left;//指向左子节点的指针
Node*m_right;//指向右子级的指针
节点(T数据){
m_data=数据;
m_left=nullptr;
m_right=nullptr;
m_parent=nullptr;
}
};
main.cpp
#include"splay_tree.h"
#include<iostream>
using namespace std;
int main(){
splay_tree<int> s1;
cout<<s1.gethead();
s1.insert(12);
s1.insert(89);
return 0;
}
#包括“splay_tree.h”
#包括
使用名称空间std;
int main(){
八字树s1;
cout仔细观察后,你的行为肯定有问题。
让我们用示意图分解左旋转代码:
这是进入旋转功能之前的样子
第一条指令Node*temp=Node->m_right
的结果如下:
这本身并没有错,但请注意,您的新节点临时缺少连接
最后,node->m_right=temp->m_left
理论上是这样的:
如您所见,node->m_right
仍然具有来自父节点和子节点的传入连接,temp->m_left
将指向自身。这就是导致分段错误的原因
要更正错误,您应该执行以下操作:
在将节点->m_分配给新节点之前,请确保已销毁所有与节点->m_的连接
不要忘记将连接添加到新的临时节点
仔细观察之后,你所做的肯定有问题。
让我们用示意图分解左旋转代码:
这是进入旋转功能之前的样子
第一条指令Node*temp=Node->m_right
的结果如下:
这本身并没有错,但请注意,您的
template<class T>
class Node{
public:
T m_data; // holds the key
Node<T>* m_parent; // pointer to the parent
Node<T>* m_left; // pointer to left child
Node<T>* m_right; // pointer to right child
Node(T data){
m_data=data;
m_left=nullptr ;
m_right=nullptr ;
m_parent=nullptr;
}
};
#include"splay_tree.h"
#include<iostream>
using namespace std;
int main(){
splay_tree<int> s1;
cout<<s1.gethead();
s1.insert(12);
s1.insert(89);
return 0;
}
Node<T>* temp= node->m_right;
node->m_right= temp->m_left;
if(temp->m_left){
temp->m_left->m_parent=node;
}
temp->m_parent=node->m_parent;
if(node->m_parent==nullptr){
this->root=temp;
}else if(node=node->m_parent->m_left){
node->m_parent->m_left=temp;
}else if(node=node->m_parent->m_right){
node->m_parent->m_right=temp;
}
temp->m_left=node;
node->m_parent=temp;
void left_rotate(Node<T>* node){
if(node==nullptr){return ;}
else{
Node<T>* temp= node->m_right;
node->m_right=temp->m_left;
if(temp->m_left){
temp->m_left->m_parent=node;
}
temp->m_parent=node->m_parent;
if(node->m_parent==nullptr){
this->root=temp;
}else if(node==node->m_parent->m_left){
node->m_parent->m_left=temp;
}else if(node== node->m_parent->m_right){
node->m_parent->m_right=temp;
}
temp->m_left=node;
node->m_parent=temp;
}
}
void right_rotate(Node<T>* node){
Node<T>* temp=node->m_left;
node->m_left=temp->m_right;
if(temp->m_right){
temp->m_right->m_parent=node;
}
temp->m_parent= node->m_parent;
if(node->m_parent==nullptr){
this->root=temp;
}else if(node==node->m_parent->m_left){
node->m_parent->m_left=temp;
}else if(node== node->m_parent->m_right){
node->m_parent->m_right=temp;
}
temp->m_right=node;
node->m_parent=temp;
}
//splay Function
void splay(Node<T>* node){
while(node->m_parent){
if(!node->m_parent->m_parent){
if(node==node->m_parent->m_left){//zig Rotation
right_rotate(node->m_parent);
}else if(node==node->m_parent->m_right){
left_rotate(node->m_parent);
}
}
else if(node==node->m_parent->m_left && node->m_parent==node->m_parent->m_parent->m_left){//Zig Zig
right_rotate(node->m_parent->m_parent);
right_rotate(node->m_parent);
}else if(node== node->m_parent->m_right && node->m_parent==node->m_parent->m_parent->m_right){//zag zag
left_rotate(node->m_parent->m_parent);
left_rotate(node->m_parent);
}else if(node==node->m_parent->m_left && node->m_parent== node->m_parent->m_parent->m_right){
right_rotate(node->m_parent);
left_rotate(node->m_parent);
}else if(node== node->m_parent->m_right && node->m_parent== node->m_parent->m_parent->m_left){
left_rotate(node->m_parent);
right_rotate(node->m_parent);
}
}
}
//Insert Function
void insert(T data){
Node<T>* new_node= new Node<T>(data);
Node<T>* y= nullptr;
Node<T>* x= this->root;
while (x!= nullptr){
y=x;
if(new_node->m_data<x->m_data){
x= x->m_left;
}
else{
x=x->m_right;
}
}
// y is a m_parent of x
new_node->m_parent=y;
if(y==nullptr){
this->root=new_node;
}else if(new_node->m_data<y->m_data){
y->m_left=new_node;
}else{
y->m_right=new_node;
}
splay(new_node);
}