13 计学

1.设多项式f(x)=a1xc1+a2xc2+…
      g(x)=b1xt1+b2xt2+…
已经表示成如下链表结构:
在这里插入图片描述
且并非按照x的方幂递增有序。试给出算法,判定是否有:g(x)=f(x)。并给出算法的时间复杂度。注:f(x)表示函数f(x)的导数。设多项式中结点的结构定义为|coef|exp|next|,其中coef表示x的系数,exp表示x的幂,next是指向下一项的指针。
思路:对两个链表,按方幂递增排序,然后再判断,f的前几项方幂若为0,则先向移动,然后两个链表同时遍历,如果c-1!=t或者a*c!=b即方幂不对或系数不对就返回false。如果循环结束,两个指针同时空,则返回true.若不同时空,说明一长一短,返回false。

typedef struct node
{
	int coef; //系数
	int exp;//方幂
	struct node *next;
}*Node;
Node sort(Node head)  //采用插入法链表排序
{
	Node dhead=(Node)malloc(sizeof(struct node));
	dhead->next=NULL;
	Node pre=dhead,p=head;//pre指向新链表,p指向待排序链表
	while(p!=NULL)
	{
		Node temp=p->next;  //temp保存p的后继
		while(pre->next!=NULL&&pre->next->exp<p->exp)//寻找插入位置
			pre=pre->next;
		p->next=pre->next;//将p插在pre后面
		pre->next=p;
		p=temp;//p继续在待排序链表里向后移动
		pre=dhead;//重置pre以便再次寻找插入位置
	}
	return dhead->next;//直接返回创建的不带空头的链表
}
bool IsEqual(Node f,Node g)
{
	Node p=sort(f),q=sort(g);
	while(p->exp==0) //幂为0的话导数为常数,不用比较,向后移
		p=p->next;
	while(p!=NULL&&q!=NULL)
	{
		if(p->exp-1!=q->exp||p->exp*p->coef!=q->coef)//方幂不对或系数不对
			return false;
		p=p->next;
		q=q->next;
	}
	if(p==NULL&&q==NULL)//同时遍历结束
		return true;
	return false;//没同时结束,说明一长一短,返回false

}

2.设二叉查找树中结点结构由下述3个域构成。
key:给出结点数据项之值;
left:给出本结点的左子结点地址;
right:给出本结点的右子结点地址。
设key域为正整数。
该二叉树根结点地址为root。
(1)编写算法,找出该二叉树先根序列的最后一个结点,要求不使用递归,不使用栈。
(2)编写算法,将key域之值大于等于给定值x的结点全部删除。

答:(1)思路:1.首先判断根是否为空 2.循环遍历,若当前结点有一个孩子结点时向下遍历,有两个孩子时,指向右孩子。3.反复执行,直到叶结点。

Tree PreOrder_Last(Tree root)
{
	if(root==NULL)
		return NULL;
	Tree p=root;
	while(1)
	{
		if(p->right!=NULL)//若有右子树,优先遍历右子树
			p=p->right;
		else if(p->left!=NULL)//只有左子树
			p=p->left;
		else
			break; //既无左子树,也无右子树,是叶子结点,结束循环
	}
	return p;
}

(2)
思路:
1.从根结点开始判断,若key小于x则向右子树遍历,同时记录前驱结点。
2.当p所指的key大于等于x时,将其入队,从该结点开始层次遍历
3.当出队元素小于x时,将其右子树入队
4.当出队元素大于等于x时,将其左子树入队,递归删除这个结点及其子树。

typedef struct node
{
	int key;
	struct node *left,*right;
}*Tree;
void Del(Tree root)//递归删除树
{
	if(root!=NULL)
	{
		Del(root->left);
		Del(root->right);
		free(root);
	}
}
void DelX(Tree root,int x)
{
	Tree queue[maxsize];
	int front=0,rear=0;
	Tree p=root,pre=NULL;
	while(p->right!=NULL&&p->key<x) //找到第一个大于等于x的结点
	{
		pre=p;
		p=p->right;
	}
	if(p->key<x)
		return;      //所有结点均小于x则无需操作
	queue[rear++]=p; //将p入队
	while(front!=rear)
	{
		p=queue[front++];//出队
		if(p->key<x)  //出队元素小于x时,将其右子树入队
			queue[rear++]=p->right;
		else  //当出队元素大于等于x时,递归删除,将其左子树入队
		{
			if(p->left!=NULL)
			{
				queue[rear++]=p->left;
				pre->right=p->left;	
			}
			else
			{
			     pre->right=NULL;
			}
			Del(p);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值