简体   繁体   English

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

[英]Problem with pointers in binary search tree deletion

I am trying to implement binary search tree operations and got stuck at deletion. 我正在尝试实施二进制搜索树操作,并被卡在删除中。

  11
 /  \
10  14 

Using inorder traversal as representation of tree initially output is 10 11 14. 使用有序遍历作为树的表示,初始输出为10 11 14。

Deleting node 10, output expected is 11 14 but I am getting 0 11 14. 删除节点10,预期输出为11 14,但我得到0 11 14。

Deleting node 14, output expected is just 11 but I am getting 0 11 67837. 删除节点14,预期输出仅为11,但我得到0 11 67837。

Please explain why I am getting wrong output. 请解释为什么我得到错误的输出。 I am not looking for any code :). 我没有在寻找任何代码:)。

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");
}

Please explain why I am getting wrong output. 请解释为什么我得到错误的输出。

Your delete function must also change the parent of the deleted Node. 您的delete功能还必须更改已删除节点的父节点。 For example, when you delete the node holding 10, you must set the root Node 's left child to NULL . 例如,当删除保留10的节点时,必须将根NodeleftNode设置为NULL Since you don't do this, when you later traverse the tree, you print out data that has already been freed. 由于不执行此操作,因此以后在遍历树时,将打印出已释放的数据。

I did not look at any code other than delete , so I can't make any guarantees about it working once this change is made. 除了delete ,我没有看到任何其他代码,因此一旦进行此更改,就无法保证其正常工作。

You're getting wrong output because your deletion code is buggy (okay, maybe that's stating the obvious). 您的输出错误是因为您的删除代码有错误(好的,也许这很明显)。

To delete from a binary search tree, you first find the node to be deleted. 要从二叉搜索树中删除,首先要找到要删除的节点。 If it's a leaf node, you set the pointer to it in its parent node to NULL, and free the node. 如果它是叶节点,则在其父节点中将指向它的指针设置为NULL,然后释放该节点。 If it's not a leaf node, you take one of two leaf nodes (either the left-most child in the right sub-tree, or the right-most child in the left sub-tree) and insert that in place of the node you need to delete, set the pointer to that node in its previous parent to NULL, and delete the node you've now "spliced out" of the tree. 如果不是叶节点,则采用两个叶节点之一(右侧子树中最左侧的子节点,或左侧子树中最右侧的子节点),然后将其插入节点需要删除,将指向该节点在其先前父节点中的节点的指针设置为NULL,然后删除您现在“剪接”出树的节点。

A couple of things really quick, 几件事真的很快,

first when you allocate the node, you really should be doing the malloc on the sizeof the type (ie Node). 首先,当您分配节点时,您实际上应该在类型的大小(即Node)上执行malloc。

Second, if you have 2 children it looks like you are not really deleting the node and rebuilding the search tree by promoting one of the children. 其次,如果您有2个孩子,则看起来您并没有真正删除节点并通过提升其中一个孩子来重建搜索树。

Other people have already got you other obvious errors. 其他人已经给您带来其他明显的错误。

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

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