俩个半小时
继续刷题组
成功又写出了俩道题目
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;
}
二十分钟
完成离散数学作业