二进制搜索树--删除函数不起作用

Binary Search Tree--delete function not working

本文关键字:函数 不起作用 删除 搜索树 二进制      更新时间:2023-10-16
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
template <class T>
struct TreeNode{
  string value;
  T key;
  TreeNode<T> *Parent;
  TreeNode<T> *LeftChild;
  TreeNode<T> *RightChild;
  TreeNode (T k,string Val)
  {
    this->value=Val;
    this->key=k;
    this->Parent=NULL;
    this->LeftChild=NULL;
    this->RightChild=NULL;
  }
};
template <class T>
class BinaryTree{
  private:
    TreeNode<T> *Root;
  public: 
       BinaryTree();
       void LoadTree(const char file[]);
       ~BinaryTree();
       void insertNode(T Key,string Val);
       void deleteNode(T Key);
       string searchNode(T Key);
       void UpdateKey(T newkey,T oldkey);
       int Height(TreeNode<T> *node);
       int height();
};
template <class T>
BinaryTree<T>::BinaryTree() 
{
   Root=NULL;                       
}
template <class T>
void BinaryTree<T>::insertNode(T Key,string Val)
{
   TreeNode<T> **temp=&Root;
   TreeNode<T> *temp1=NULL;
   if (*temp==NULL)
   {
     Root=new TreeNode<T>(Key,Val);
     return;
   }
   else
   {            
     while (*temp!=NULL)
     {
       temp1=*temp;
       if (temp1->key>Key)
       {
           temp=&(*temp)->LeftChild;
       }
       else if (temp1->key<Key)
       {
            temp=&(*temp)->RightChild;
       }
     }
   }
   *temp=new TreeNode<T>(Key,Val);              
   (*temp)->Parent=temp1;
}
template <class T>
void BinaryTree<T>::LoadTree(const char *file)
{
  ifstream fin;
  fin.open(file);
  string buffer;
  T buff;
  while (!fin.eof())
  {
      getline(fin,buffer,'~');
      fin>>buff;
      if (!buff)
      continue; 
      insertNode(buff,buffer);
  }          
  fin.close();
}  
void BinaryTree<T>::deleteNode(T Key)
{
  TreeNode<T> *temp=Root;
  TreeNode<T> *temp1=temp;
  while (temp!=NULL)
  {
       if (temp->key==Key)
       {
           temp1=temp;               
           if (temp==Root)
           {
               TreeNode<T> *temp2=Root;
               temp2=temp2->RightChild;
               while (temp2->LeftChild!=NULL)
               {
                     temp2=temp2->LeftChild;
               }
               temp->key=temp2->key;
               temp->value=temp2->value;
               delete temp2;            
           } 
           else if (temp->RightChild==NULL)
           {
                TreeNode<T> *temp2=temp;
                temp2=temp->Parent;
                if (temp2->RightChild==temp)
                {
                    temp2->RightChild=temp->LeftChild;
                    (temp->LeftChild)->Parent=temp2;
                }
                else if (temp2->LeftChild==temp)
                {
                    temp2->LeftChild=temp->LeftChild;
                    (temp->LeftChild)->Parent=temp2;
                }
                delete temp1;
                delete temp;
                return;
           }
           else if (temp->LeftChild==NULL)
           {
                TreeNode<T> *temp2=temp;
                temp2=temp->Parent;
                if (temp2->RightChild==temp)
                {
                    temp2->RightChild=temp->RightChild;
                    (temp->RightChild)->Parent=temp2;
                }
                else if (temp2->LeftChild==temp)
                {
                    temp2->LeftChild=temp->RightChild;
                    (temp->RightChild)->Parent=temp2;
                }
                delete temp1;
                delete temp;
                return;
           }
           else if (temp->RightChild!=NULL)
           {
               TreeNode<T> *tmp=temp; 
               temp=temp->RightChild;
               if (temp->LeftChild!=NULL)
               {
                   while (temp->LeftChild!=NULL)
                   {
                       tmp=temp;  
                       temp=temp->LeftChild;
                   }      
               }
               if (tmp!=temp1)
               tmp->LeftChild==NULL;
               else
               temp1->RightChild==NULL;
               temp1->key=temp->key;
               temp1->value=temp->value;
               delete temp;
               return;
           }
       }
       if (temp->key>Key)
       {
           temp=temp->LeftChild;
       }
       else if (temp->key<Key)
       {
            temp=temp->RightChild;
       }
 }                            
 return;
}        

这是我正在制作的二进制搜索树代码的一部分。当我运行删除功能时,我遇到了一个问题,即对于某些节点,我收到错误"testing.exe已停止工作"。testing是我的主文件的名称。我检查了一遍又一遍,但似乎没有发现问题。有人看到问题了吗?感谢

您的代码肯定有不止一个问题。

假设要删除的密钥存储在根:

if (temp->key==Key)
{
  temp1=temp;               
  if (temp->RightChild==NULL)
  {
    TreeNode<T> *temp2=temp;
    temp2=temp->Parent;         // temp2 will be NULL here 
    if (temp2->RightChild==temp)
    {
      temp2->RightChild=temp->LeftChild;  // thus dereferencing NULL either here
      (temp->LeftChild)->Parent=temp2;
    }
    else if (temp2->LeftChild==temp)
    {
      temp2->LeftChild=temp->LeftChild;   // ... or here
      (temp->LeftChild)->Parent=temp2;
    }
    delete temp1;
    delete temp;
    return;
  }

仔细看一下代码的轮廓,案例处理似乎是不正确的:

if (temp->key==Key)
{
  temp1=temp;               
  if (temp->RightChild==NULL)
  {
     // do something
  }
  else if (temp->LeftChild==NULL)
  {
     // do something
  }
  else if (temp->RightChild!=NULL)
  {
     // do something
  }
  else if (temp->LeftChild!=NULL && temp->RightChild==NULL)
  {
     // code never reached
  }
}

在删除temp1temp的两种情况下,它们都指向同一地址。