C++ Splay树实现

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

我正在尝试实现一个splay树。但是splay()函数调用的left_rotate和right_rotate函数中出现了一个分段错误。我试过调试,但没有任何线索。我哪里做错了! 我认为有某种逻辑错误。 这是我的密码:

八字树

#包括“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);
    }