这段代码:
- 刀片
- 搜索
- 打印各种遍历
- 删除
删除是问题所在,我自己完成了这段代码(所以这可能不是常规方法)。我将删除分为三个部分进行检查:
- 如果目标节点有两个子节点
- 如果目标节点有一个子节点
- 如果目标节点没有子节点
该程序的每个部分都运行正确,正确的输出(只是所有内容!),除非根是唯一剩下的节点并且我们试图删除根。
它进入非节点函数(在函数中有根的特殊情况),甚至打印“你已经删除了内存中唯一的节点”。再次提供所有选项。但是在此之后选择任何选项都会显示错误。在尝试打印各种遍历,例如它在检查遍历时打印一个无限的地址列表,最终 .exe 文件停止而不是打印“内存中没有二叉树”。
#include <stdio.h>
#include <stdlib.h>
struct bt
{
struct bt *left;
int data;
struct bt *right;
};
struct bt *root=NULL,**sp=NULL;
void insertion(struct bt**,int);
void prtraversal(struct bt**);
void intraversal(struct bt**);
void potraversal(struct bt**);
void search(struct bt**,int);
void del(struct bt **n,int key);
void nonode(struct bt **n);
void onenode(struct bt **n);
void bothnode(struct bt **n);
main()
{
int ch,key;
printf("******\n\n The program automatically avoids inclusion of repeat numbers\n\n**********");
while(1)
{
printf("\nenter your choice\n1 for insertion\n2 for search\n3 for Various Traversal\n4 for deletion\n5 for exit\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("Enter your Key for insertion\n");
scanf("%d",&key);
insertion(&root,key);
break;
case 2:
if(root!=NULL)
{
printf("Enter your Key for search\n");
scanf("%d",&key);
search(&root,key);
}
else
{
printf("\n NO BINARY TREE IN MEMORY\n");
}
break;
case 3:
if(root!=NULL)
{
printf("\n\nPREORDER TRAVERSAL:");
prtraversal(&root);
printf("\n\nINORDER TRAVERSAL:");
intraversal(&root);
printf("\n\nPOSTORDER TRAVERSAL:");
potraversal(&root);
}
else
{
printf("\n NO BINARY TREE IN MEMORY\n");
}
break;
case 4:
if(root!=NULL)
{
printf("Enter your Key for Delete\n");
scanf("%d",&key);
del(&root,key);
}
else
{
printf("\n NO BINARY TREE IN MEMORY\n");
}
break;
case 5:
exit(1);
default:
printf("\n Wrong Choice\n");
}
sp=NULL;
}
}
void del(struct bt **n,int key)
{
if((*n)!=NULL)
{
if(key<(*n)->data)
del(&((*n)->left),key);
else if(key>(*n)->data)
del(&((*n)->right),key);
else if(key==(*n)->data)
{
printf("\nELEMENT FOUND\n");
printf("\n DELETION UNDERWAY\n");
sp=n;
if(((*n)->right)!=NULL && ((*n)->left)!=NULL)
{
bothnode(&((*n)->left));
}
else if(((*n)->right)!=NULL && ((*n)->left)==NULL)
{
onenode(&((*n)->right));
}
else if(((*n)->left)!=NULL && ((*n)->right)==NULL)
{
onenode(&((*n)->left));
}
else if(((*n)->left)==NULL && ((*n)->right)==NULL)
{
nonode(&root);
}
}
}
else
{
printf("\nELEMENT NOT FOUND\n");
}
}
void nonode(struct bt **n) //deletes the target node without any child,root address is provided to struct bt **n
{
struct bt **parent=n;//stores address of node just before target node,will be updated in this function
if(sp!=&root)//target node address stored in sp from a previous function
{
while((*n)->data!=(*sp)->data)//to find address of node just before target node and store it in struct bt **parent
{
parent=n;//frequent parent update as struct bt **n traverses tree
if(((*sp)->data)<((*n)->data))
n=&((*n)->left);
if(((*sp)->data)>((*n)->data))
n=&((*n)->right);
}
if((*parent)->right==(*sp))//checks if parent's right contains address of target node
{
(*parent)->right=NULL;
free(*sp);
}
else if((*parent)->left==(*n))//else checks if parent's left contains address of target node
{
(*parent)->left=NULL;
free(*n);
}
}
else if(sp==&root)//if the root node has to be deleted,no child on either side,only one node in tree
{
free(*sp);
printf("\nYOU DELETED THE ONLY NODE IN MEMORY\n");
}
}