C语言 排序二叉树 删除某个结点

#include<stdio.h>
#include<stdlib.h>

struct treenode
{
 int data;
 struct treenode *left,*right;
};

struct treenode *createBiTree(struct treenode **p,int x)

 if(*p==NULL)
 {
  *p=(struct treenode *)malloc(sizeof(struct treenode));
  if (*p==NULL)
  {
   printf("内存分配失败!\n");
   exit(0);
  }
  (*p)->data=x;
  (*p)->left=(*p)->right=NULL;
 }
 else if(x<(*p)->data)
  createBiTree(&(*p)->left,x);
 else
  createBiTree(&(*p)->right,x);
 return (*p);
}

int treeDepth(struct treenode *p)
{
 int ldepth,rdepth;
 if(p==NULL)
  return 0;
 else
 {
  ldepth=treeDepth(p->left);
  rdepth=treeDepth(p->right);

  return (ldepth>rdepth)?(ldepth+1):(rdepth+1);
 }
}

void traverse(struct treenode *p)
{
 if(p!=NULL)
 {
  printf("%d",p->data);
  if(p->left!=NULL||p->right!=NULL)
  {
   printf("(");
   traverse(p->left);
   if(p->right!=NULL)
    printf(",");
   traverse(p->right);
   printf(")");
  }
 }
}
//树根为p的排序二叉树中,找出结点值为x的父结点
struct treenode * findNode(struct treenode *p,int x)
{
 struct treenode *parent=NULL;

 while(p!=NULL)
 {
  if(x<p->data)
  {
   parent=p;
   p=p->left;
  }
  else if(x>p->data)
  {
   parent=p;
   p=p->right;
  }
  else if(x==p->data)
   return parent;
 }

 return NULL;
}
//删除父结点为px,子结点值为x的结点
void deleteNode(struct treenode *&px,int x)
{
 //p1是p的父结点,ps是s的父结点
 struct treenode *p=NULL,*p1=NULL,*ps=NULL,*s=NULL;
 p1=px;

 if(p1==NULL)
 {
  printf("删除不成功,该结点不存在!\n");
  return ; 
 }
 //确定p是p1的左孩子还是右孩子
 if(p1->left==NULL)
  p=p1->right;
 else if(p1->right==NULL)
  p=p1->left;
 else
 {
  if(p1->left->data==x)
   p=p1->left;
  else p=p1->right;
 }
 //删除结点p:
 //1、p左右皆为空
 if((p->left==NULL)&&(p->right==NULL))
 {
  if(p1->left==p)
   p1->left=NULL;
  else p1->right=NULL;

  free(p);
 }
 //2、p只有右为空
 else if((p->left!=NULL)&&(p->right==NULL))
 {
  if(p1->left==p)
   p1->left=p->left;
  else p1->right=p->left;

  free(p);
 }
 //3、p只有左为空
 else if((p->left==NULL)&&(p->right!=NULL))
 {
  if(p1->left==p)
   p1->left=p->right;
  else p1->right=p->right;

  free(p);
 }
 //4、p的左右皆不为空
 else if((p->left!=NULL)&&(p->right!=NULL))
 {
  s=p->left;
  if(s->right==NULL)
  {
   p->data=s->data;
   p->left=s->left;
   free(s);

   return ;
  }
  while(s->right!=NULL)
  {
   ps=s;
   s=s->right;
  }
  if(s->left==NULL)
  {
   p->data=s->data;
   ps->right=NULL;
  }
  else if(s->left!=NULL)
   ps->right=s->left;
  free(s);
 }
}

void main(void)
{
 FILE *fp=NULL;
 int x;
 int depth;
 struct treenode *root=NULL,*parent=NULL;

 //读取文件,建立排序二叉树链表
 fp=fopen("sy5.txt","r");
 if(!fp)
 {
  printf("读取文件错误!");
  exit(0);
 }
 while(!feof(fp))
 {   
  fscanf(fp,"%d",&x);
  if(x==0)
   break;
  createBiTree(&root,x);
 }
 fclose(fp);
 //初始化二叉树后,输出二叉树
 printf("先序遍历二叉树为:\n");
 traverse(root);  printf("\n");
 depth=treeDepth(root);
 printf("二叉树的深度为: %d\n",depth);

 //删除结点
 printf("请输入要删除的结点值:\n");
 scanf("%d",&x);

 parent=findNode(root,x);
 deleteNode(parent,x);

 //删除之后,输出二叉树
 printf("=============================\n");
 printf("删除成功!\n删除之后,先序遍历二叉树为:\n");
 traverse(root);  printf("\n");
 depth=treeDepth(root);
 printf("二叉树的深度为: %d\n",depth);
}

//要先建一个记事本文件以便读取数据

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值