繁体   English   中英

二进制搜索树删除中的指针问题

[英]Problem with pointers in binary search tree deletion

我正在尝试实施二进制搜索树操作,并被卡在删除中。

  11
 /  \
10  14 

使用有序遍历作为树的表示,初始输出为10 11 14。

删除节点10,预期输出为11 14,但我得到0 11 14。

删除节点14,预期输出仅为11,但我得到0 11 67837。

请解释为什么我得到错误的输出。 我没有在寻找任何代码:)。

typedef struct _node{
  int data;
  struct _node *left;
  struct _node *right;
} Node;

Node* bstree_search(Node *root, int key)
{
  if(root == NULL){
    return root;
  }
  // Based on binary search relation, key can be found in either left,
  // right, or root.
  if(key > root->data)
    return bstree_search(root->right, key);
  else if(key < root->data)
    return bstree_search(root->left, key);
  else
    return root;
}
void bstree_insert(Node **adroot, int value)
{
  // since address of address(root is itself address) is passed we can change root.
  if(*adroot == NULL){
    *adroot = malloc(sizeof(**adroot));
    (*adroot)->data = value;
    (*adroot)->right = (*adroot)->left = NULL;
    return;
  }
  if(value > (*adroot)->data)
    bstree_insert(&(*adroot)->right, value);
  else
    bstree_insert(&(*adroot)->left, value);
}

void bstree_inorder_walk(Node *root)
{
  if(root != NULL){
    bstree_inorder_walk(root->left);
    printf("%d ",root->data);
    bstree_inorder_walk(root->right);
  }
}
void bstree_delete(Node **adnode)
{
  //Node with no children or only one child
  Node *node, *temp;
  node = temp = *adnode;
  if((*adnode)->right == NULL || (*adnode)->left == NULL){
    if((*adnode)->right == NULL){
      *adnode = (*adnode)->left;
    }else{
      *adnode = (*adnode)->right;
    }
  }else{ // Node with two children

  }
  free(temp);
}

int main()
{
  Node *root = NULL;
  Node *needle = NULL;
  int i,elems[] = {11,10,14};

  for(i = 0; i < 3; ++i)
    bstree_insert(&root,elems[i]);

  bstree_inorder_walk(root);
  printf("\n");

  needle = bstree_search(root, 10);
  bstree_delete(&needle);
  bstree_inorder_walk(root);
  printf("\n");

  needle = bstree_search(root, 14);
  bstree_delete(&needle);
  bstree_inorder_walk(root);
  printf("\n");
}

请解释为什么我得到错误的输出。

您的delete功能还必须更改已删除节点的父节点。 例如,当删除保留10的节点时,必须将根NodeleftNode设置为NULL 由于不执行此操作,因此以后在遍历树时,将打印出已释放的数据。

除了delete ,我没有看到任何其他代码,因此一旦进行此更改,就无法保证其正常工作。

您的输出错误是因为您的删除代码有错误(好的,也许这很明显)。

要从二叉搜索树中删除,首先要找到要删除的节点。 如果它是叶节点,则在其父节点中将指向它的指针设置为NULL,然后释放该节点。 如果不是叶节点,则采用两个叶节点之一(右侧子树中最左侧的子节点,或左侧子树中最右侧的子节点),然后将其插入节点需要删除,将指向该节点在其先前父节点中的节点的指针设置为NULL,然后删除您现在“剪接”出树的节点。

几件事真的很快,

首先,当您分配节点时,您实际上应该在类型的大小(即Node)上执行malloc。

其次,如果您有2个孩子,则看起来您并没有真正删除节点并通过提升其中一个孩子来重建搜索树。

其他人已经给您带来其他明显的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM