【发布时间】:2021-03-12 09:07:40
【问题描述】:
二叉搜索树操作。
第一次插入节点时遇到问题。
函数根的变化不会反映在主函数中。
尝试在主函数中初始化根,它工作正常,就像插入函数在这种情况下工作正常。但是当树是空的并且我们第一次必须添加一个元素时,它不会被添加到树中。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *left, *right;
}node;
void insert(node *root, int x)
{
node *newrec, *p, *q;
newrec = (node *) malloc(sizeof(node));
newrec->data = x;
newrec->left = NULL;
newrec->right = NULL;
if(root == NULL)
{
root = newrec;
return;
}
p = root;
while(p != NULL)
{
q = p;
if(x <= p->data)
p = p->left;
else
p = p->right;
}
if(x <= q->data)
q->left = newrec;
else
q->right = newrec;
}
void delete(node *root, int x)
{
node *p, *q, *r;
if(root == NULL)
{
printf("\nTree is Empty");
return;
}
p = root;
while(p != NULL && p->data != x)
{
q = p;
if(x <= p->data)
p = p->left;
else
p = p->right;
}
if(p == NULL)
{
printf("\nElement not Found");
return;
}
if(p->left == NULL && p->right == NULL) // 0 child
{
if(p == root)
root = NULL;
else if(q->left == p)
q->left = NULL;
else
q->right = NULL;
free(p);
return;
}
if(p->left != NULL && p->right == NULL) // (1 child) left child but not right child
{
if(p == root)
root = p->left;
else if(q->left == p)
q->left = p->left;
else
q->right = p->left;
p->left = NULL;
free(p);
return;
}
if(p->left == NULL && p->right != NULL) // (1 child) right child but not left child
{
if(p == root)
root = p->right;
else if(q->left == p)
q->left = p->right;
else
q->right = p->right;
p->right = NULL;
free(p);
return;
}
// 2 child
r = p->right;
q = p;
while(r->left != NULL)
{
q = r;
r = r->left;
}
p->data = r->data;
if(q->left == r)
q->left = r->right;
else
q->right = r->right;
r->left = NULL;
r->right = NULL;
free(r);
}
void inorder(node *root)
{
if(root != NULL)
{
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}
void preorder(node *root)
{
if(root != NULL)
{
printf("%d ", root->data);
preorder(root->left);
preorder(root->right);
}
}
void postorder(node *root)
{
if(root != NULL)
{
postorder(root->left);
postorder(root->right);
printf("%d ", root->data);
}
}
int main()
{
int ch, x;
node *root1;
/*
root1 = (node *) malloc(sizeof(node));
root1->data = 1;
root1->left = NULL;
root1->right = NULL;
*/
root1 = NULL;
while(1)
{
printf("\nMENU");
printf("\n1.Insert 2.Delete 3.Display 4.Exit");
printf("\nEnter choice : ");
scanf("%d", &ch);
if(ch == 4)
break;
switch(ch)
{
case 1: printf("\nEnter element to Insert : ");
scanf("%d", &x);
insert(root1, x);
printf("\n%d ", root1->data);
break;
case 2: printf("\nEnter element to delete : ");
scanf("%d", &x);
delete(root1, x);
break;
case 3: if(root1 == NULL)
printf("\nTree is Empty");
else
{
printf("\nInorder : ");
inorder(root1);
printf("\nPreorder : ");
preorder(root1);
printf("\nPostorder :");
postorder(root1);
}
break;
default: printf("\nInvalid Choice");
}
}
return 0;
}
【问题讨论】:
-
在
insert函数中赋值root = newrec不会做任何事情。一旦函数结束,root的生命周期也会结束,对它的所有修改都将丢失。您需要在此处模拟通过引用传递。或者返回新的根目录。 -
此外,树的迭代处理增加了很多复杂性。使用递归可以更好、更简单地处理树。
-
如何通过引用从主函数传递root1?并且在您告诉搜索的情况下进行迭代处理?
-
如果问题在于引用,那么为什么插入(当 root 不为 NULL)和删除工作正常?
标签: c tree binary-search-tree