三月八日

俩个半小时
继续刷题组
成功又写出了俩道题目
在这里插入图片描述
D题不该错的,当时没有想到如果输入的是0,应该就有一个人留下,但是我没有想到这点,今天灵光一闪,突然想到了,就通过了。
C题,大意就是 给你n只虫子,m对虫子之间的关系,问他们之间是否存在同性恋。看懂题目意思之后开始想了一会,觉得就是只要判断某个小堆里面虫子数目的奇偶性就可以了,但是是错误的,后面查了一下才知道需要种类并查集,种类并查集的关键在于与结点与根结点的距离, 如果距离是奇数那么性别就和跟结点相反,如果是偶数就和跟结点性别相同。我用r[x]记录x与其父亲节点的关系, r[x]=0表同性, rank[x]=1表异性。
然后才开始动刀的,用另外一个数组储存到根节点的距离,然后再判断奇偶性才可以
明天再试试E题吧;
俩小时
学数据结构
二叉排序树
建立结构

typedef struct BiTNode
{
 int date;
 struct BiTNode *lchild,*rchild;
 //leftchild左孩子,right child右孩子 
}BiTNode,*BiTree;

二叉排序树查找

//二叉排序树查找
//递归查找二叉排序树中是否存在key(要查找的数)
//指针f指向T的双亲,其初始值为NULL
//若查找成功,则指针p指向该数据元素的结点,并返回1 
//否则指针p指向查找路径上访问的最后一个结点并返回0
int SearchBST(BiTree T,int key,BiTree f,BiTree *p)
//T为二叉链表,key表示要查找的关键字,f指向T的双亲,p是为了查找成功后可以得到查找的结点位置 
{
 if(!T)//查找不成功,即T为空的时候 
 {
  *p=f;
  return 0;
 }
 else
 if(key==T->date)//查找成功 
 {
  *p=T;
  return 1;
 }
 else
 if(key<T->date)//小于的话在左子树继续查找 
 {
  return SearchBST(T->lchild,key,T,p);
 }
 else//大于从右子树继续查找 
 return SearchBST(T->rchild,key,T,p);
 } 

二叉排序树的插入操作

//当二叉排序树T中不存在关键字等于key的数据元素时才执行插入操作
//插入后返回1,否则返回0
int InsertBST(BiTree *T,int key)
{
 BiTree p,s;
 if(!SearchBST(*T,key,NULL,&p))//如果没有查找到key继续执行 
 {
  s=(BiTree)malloc(sizeof(BiTree));
  s->date=key;
  s->lchild=s->rchild=NULL;
  if(!p)
  *T=s;
  else
  if(key<p->date)
  p->lchild=s;
  else
  p->rchild=s;
  return 1;
 }
 else
 return 0;
} 

二叉排序树的删除操作

//二叉排序树的删除操作
//若二叉排序树T中存在关键字等于key的数据元素时,删除该元素结点
//并返回1,否则返回0 
int DeleteBSt (BiTree *T,int key)
{
 if(!T)
 return 0;
 else
 {
  if(key==(*T)->date)
  return Delete(T);
  else
  if(key<(*T)->date)
  return DeleteBST(&(*T)->lchild,key);
  else
  return DeleteBST(&(*T)->rchild,key);
 }
}
//从排序二叉树中删除结点p,并重接它的左子树或者右子树 
int Delete(BiTree *p)
{
 BiTree q,s;
 if((*p)->rchild==NULL)//右子树为空则只需重接左子树 
 {
  q=*p;
  *p=(*p)->lchild;
  free(q);
 }
 else
 if((*p)->lchild==NULL)//只需重接右子树 
 {
  q=*p;
  *p=(*p)->rchild;
  free(q);
 }
 else//左右均不为空 
 {
  q=*p;
  s=(*p)->lchild;
  while(s->rchild)//转左,然后向右到尽头(找到待删节点的前驱) 
  {
   q=s;
   s=s->rchild;
  }
  (*p)->date=s->date;//s指向被删结点的直接前驱 
  if(q!=*p)
  q->rchild=s->lchild;//重接q的右子树 
  else
  q->lchild=s->lchild;//重接q的左子树 
  free(s);
 }
 return 1;
}

完整代码

#include<stdio.h>
#include<stdlib.h>
//建立二叉树的结构 
typedef struct BiTNode
{
 int date;
 struct BiTNode *lchild,*rchild;//leftchild左孩子,right child右孩子 
}BiTNode,*BiTree;
//二叉排序树查找
//递归查找二叉排序树中是否存在key(要查找的数)
//指针f指向T的双亲,其初始值为NULL
//若查找成功,则指针p指向该数据元素的结点,并返回1 
//否则指针p指向查找路径上访问的最后一个结点并返回0
int SearchBST(BiTree T,int key,BiTree f,BiTree *p)//T为二叉链表,key表示要查找的关键字,f指向T的双亲,p是为了查找成功后可以得到查找的结点位置 
{
 if(!T)//查找不成功,即T为空的时候 
 {
  *p=f;
  return 0;
 }
 else
 if(key==T->date)//查找成功 
 {
  *p=T;
  return 1;
 }
 else
 if(key<T->date)//小于的话在左子树继续查找 
 {
  return SearchBST(T->lchild,key,T,p);
 }
 else//大于从右子树继续查找 
 return SearchBST(T->rchild,key,T,p);
 } 
 //二叉排序树的插入操作
//当二叉排序树T中不存在关键字等于key的数据元素时才执行插入操作
//插入后返回1,否则返回0
int InsertBST(BiTree *T,int key)
{
 BiTree p,s;
 if(!SearchBST(*T,key,NULL,&p))//如果没有查找到key继续执行 
 {
  s=(BiTree)malloc(sizeof(BiTree));
  s->date=key;
  s->lchild=s->rchild=NULL;
  if(!p)
  *T=s;
  else
  if(key<p->date)
  p->lchild=s;
  else
  p->rchild=s;
  return 1;
 }
 else
 return 0;
} 
//二叉排序树的删除操作
//若二叉排序树T中存在关键字等于key的数据元素时,删除该元素结点
//并返回1,否则返回0 
int DeleteBSt (BiTree *T,int key)
{
 if(!T)
 return 0;
 else
 {
  if(key==(*T)->date)
  return Delete(T);
  else
  if(key<(*T)->date)
  return DeleteBST(&(*T)->lchild,key);
  else
  return DeleteBST(&(*T)->rchild,key);
 }
}
//从排序二叉树中删除结点p,并重接它的左子树或者右子树 
int Delete(BiTree *p)
{
 BiTree q,s;
 if((*p)->rchild==NULL)//右子树为空则只需重接左子树 
 {
  q=*p;
  *p=(*p)->lchild;
  free(q);
 }
 else
 if((*p)->lchild==NULL)//只需重接右子树 
 {
  q=*p;
  *p=(*p)->rchild;
  free(q);
 }
 else//左右均不为空 
 {
  q=*p;
  s=(*p)->lchild;
  while(s->rchild)//转左,然后向右到尽头(找到待删节点的前驱) 
  {
   q=s;
   s=s->rchild;
  }
  (*p)->date=s->date;//s指向被删结点的直接前驱 
  if(q!=*p)
  q->rchild=s->lchild;//重接q的右子树 
  else
  q->lchild=s->lchild;//重接q的左子树 
  free(s);
 }
 return 1;
}
int main()
{
 int n,i;
 BiTree T=NULL;
 while(~scanf("%d",&n))
 {
   int a[10000];
  for(i=1;i<=n;i++)
  {
   scanf("%d",&a[i]);
   InsertBST(&T,a[i]);
  }
 }
 return 0;
 } 

二十分钟
完成离散数学作业
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值