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);
}
}
}