线性结构---链表

链表


一元多项式求导   (20分)

设计函数求一元多项式的导数。

输入格式:

以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。

输入样例:

3 4 -5 2 6 1 -2 0

输出样例:

12 3 -10 1 6 0

解题思路:题中已说明绝对值不超过1000,则可以知晓最大的数据量是2000,此时也可以使用数组存储(注意下标的对应,此处有偏移量,所以存在负指数的情况),数组下标作为指数,数组值为系数;用数学中的定义求导,按照题目要求,如果求导后系数为零,则不输出。当然也有特殊情况,当求导后多项式为零时,输出”0 0“。我分别用结构体数组和链表实现以上求导过程,并没有使用整形数组。

提交代码:

编译器:g++

#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXN = 1002;
struct inf{
    int cof, exp;
}arr[MAXN];//定义结构体数组,cof表示系数,exp表示指数
int main()
{
    int cof, exp, index = 0;
    while(~scanf("%d%d",&cof, &exp))//输入到文件结束为止,并模拟求导过程
    {
        if(cof != 0)
        {
            if(exp != 0)
            {
                arr[index].cof = cof * exp;
                arr[index].exp = exp - 1;
                index++;
            }
        }
    }
    if(index == 0) printf("0 0");
    for(int i = 0; i < index; ++i)//输出结果
    {
        if(i) printf(" ");
        printf("%d %d",arr[i].cof,arr[i].exp);
    }
    return 0;
}

#include <iostream>
#include <stdio.h>
using namespace std;
typedef struct Link link;
struct Link{
	int cof,exp;
	link *next;
};//定义链表单个节点结构
int main()
{
	int cof,exp;
 	link *head=NULL,*tail=NULL;
	while(~scanf("%d%d",&cof,&exp))
 	{
		if(exp && cof)
		{
			link *tmp=(link *)malloc(sizeof(link));//申请动态内存空间
			tmp->next=NULL;
			tmp->cof=cof*exp,tmp->exp=exp-1;//赋值
			if(head==NULL)//链表的创建
				head=tmp,tail=head;
			else
				tail->next=tmp;
			tail=tmp;
		}
	}
	if(head==NULL)//输出
		printf("0 0\n");
	while(head)
	 {
 		printf("%d %d",head->cof,head->exp);
		if(head->next) printf(" ");
		    link *tmp=head;
 		head=head->next;
 		free(tmp);
 	}
 	return 0;
}


一元多项式的乘法与加法运算   (20分)

设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0

输入样例:

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

输出样例:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0

解题思路:

采用函数,封装加法和乘法。先考虑加法,如果指数相同则进行加法操作,如果不同,则将链表按指数递增方式排列。

对于乘法,我们使用分配律,每一个元素与多项式相乘必然的到一个新的多项式,之后的操作无非就是将这若干新的多项式重新做加法运算。

可以在纸上模拟一下该过程,在结合代码体会。

提交代码

编译器:g++

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct inf ply;
struct inf{
    int cof,exp;
    struct inf *next;
};//定义链表结构
ply *Create(ply *p,int n);//创建链表
ply *Add(ply *p1,ply *p2);//加法
ply *Mul(ply *p1,ply *p2);//乘法
void OutPut(ply *p);//输出
int main(int argc, const char * argv[])
{
    int n;
    ply *p1=NULL,*p2=NULL;
    scanf("%d",&n);
    p1=Create(p1,n);
    scanf("%d",&n);
    p2=Create(p2,n);
    
    ply *mul=Mul(p1, p2);
    OutPut(mul);
    ply *add=Add(p1, p2);
    OutPut(add);
    return 0;
}
ply *Create(ply *p,int n)
{
    ply *tail=NULL;
    for(int i=0;i<n;++i)
    {
        ply *tmp = (ply *)malloc(sizeof(ply));
        tmp->next=NULL;
        scanf("%d%d",&(tmp->cof),&(tmp->exp));
        if(p==NULL)
            p=tmp;
        else
            tail->next=tmp;
        tail=tmp;
    }
    return p;
}
ply *Add(ply *p1,ply *p2)
{
    ply *p=(ply *)malloc(sizeof(ply)),*tail=p;
    p->next=NULL;
    while(p1&&p2)
    {
        ply *tmp=(ply *)malloc(sizeof(ply));
        if(p1->exp>p2->exp)
        {
            tmp->cof=p1->cof;tmp->exp=p1->exp;
            tmp->next=NULL;
            p1=p1->next;
        }
        else if(p1->exp<p2->exp)
        {
            tmp->cof=p2->cof;tmp->exp=p2->exp;
            tmp->next=NULL;
            p2=p2->next;
        }
        else//指数相同时,系数相加;否则链表按递增排列
        {
            tmp->cof=p1->cof+p2->cof;
            tmp->exp=p1->exp;
            tmp->next=NULL;
            p1=p1->next;p2=p2->next;
        }
        if(tmp->cof)//判断系数是否为零
            tail->next=tmp,tail=tail->next;
    }
    while (p1)//将剩余的元素放入链表
        tail->next=p1,p1=p1->next,tail=tail->next;
    while (p2)
        tail->next=p2,p2=p2->next,tail=tail->next;
    return p->next;
}
ply *Mul(ply *p1,ply *p2)
{
    ply *mul=NULL;
    while (p1)//采用分配律
    {
        ply *add=NULL,*tail=NULL,*p=p2;
        while (p)
        {
            ply *tmp=(ply *)malloc(sizeof(ply));
            tmp->next=NULL;
            tmp->cof=p1->cof*p->cof;
            tmp->exp=p1->exp+p->exp;
            if(tmp->cof)
            {
                   if(add==NULL)
                    add=tmp,tail=add;
                else
                    tail->next=tmp;
                tail=tmp;    
            }
            p=p->next;
        }
        mul=Add(mul, add);//将得到新链表,与之前的结果做加法操作
        p1=p1->next;
    }
    return mul;
}
void OutPut(ply *p)
{
    if(p==NULL)
        printf("0 0");
    while (p) {
        printf("%d %d",p->cof,p->exp);
        if(p->next!=NULL)
            printf(" ");
        p=p->next;
    }
    printf("\n");
}

两个有序链表序列的合并   (20分)

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的并集新非降序链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1-11表示序列的结尾(−1-11不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 3 5 -1
2 4 6 8 10 -1

输出样例:

1 2 3 4 5 6 8 10

解题思路:将相同元素过滤,取其中一个,并按非递减排列

提交代码:

编译器:g++

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct node Node;
struct node{
    int data;
    struct node *next;
};
Node *Create(void);
Node *Merge(Node *l1, Node *l2);//做合并操作
void Output(Node *l);
int main()
{
    Node *l1, *l2;
    l1 = Create();
    l2 = Create();
    Node *l = Merge(l1,l2);//合并两个链表
    Output(l);
    return 0;
}
Node *Create(void)
{
    int num;
    Node *head = NULL, *tail = NULL;
    do{
        scanf("%d",&num);
        if(num > 0)
        {
            Node *p = (Node *)malloc(sizeof(Node));
            p->data = num;
            p->next = NULL;
            if(head == NULL) head = p,tail = head;
            else tail->next = p, tail = tail->next;
        }
    }while(num != -1);
    return head;
}
Node *Merge(Node *l1, Node *l2)
{
    Node *head = NULL, *tail = NULL;
    if(l1 == NULL && l2 == NULL) return head;
    else if(l1 == NULL) return l2;
    else if(l2 == NULL) return l1;
    else if(l1->data < l2->data) head = l1, l1 = l1->next;
    else head = l2, l2 = l2->next;
    tail = head;
    while(l1 && l2)//当链表非空时,进行合并
    {
        if(l1->data < l2->data) tail->next = l1, l1 = l1->next;
        else tail->next = l2, l2 = l2->next;
        tail = tail->next;
    }
    while(l1) tail->next = l1, l1 = l1->next, tail = tail->next;
    while(l2) tail->next = l2, l2 = l2->next, tail = tail->next;
    return head;
}
void Output(Node *l)
{
    if(l == NULL) printf("NULL");
    while(l)
    {
        printf("%d",l->data);
        if(l->next) printf(" ");
        l = l->next;
    }
}

两个有序链表序列的交集   (20分)

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1-11表示序列的结尾(−1-11不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 2 5 -1
2 4 5 8 10 -1

输出样例:

2 5

解题思路:

将链表中相同的元素取出,并舍弃其余不同元素。

提交代码:

编译器:g++

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct node Node;
struct node{
    int data;
    struct node *next;
};
Node *Create(void);
Node *Merge(Node *l1, Node *l2);//采用类似合并的操作
void Output(Node *l);
int main()
{
    Node *l1, *l2;
    l1 = Create();
    l2 = Create();
    Node *l = Merge(l1,l2);
    Output(l);
    return 0;
}
Node *Create(void)
{
    int num;
    Node *head = NULL, *tail = NULL;
    do{
        scanf("%d",&num);
        if(num > 0)
        {
            Node *p = (Node *)malloc(sizeof(Node));
            p->data = num;
            p->next = NULL;
            if(head == NULL) head = p,tail = head;
            else tail->next = p, tail = tail->next;
        }
    }while(num != -1);
    return head;
}
Node *Merge(Node *l1, Node *l2)
{
    Node *head = NULL, *tail = NULL;
    if(l1 == NULL || l2 == NULL) return NULL;
    while(l1 && l2)
    {
        if(l1->data < l2->data) l1 = l1->next;
        else if(l1->data > l2->data) l2 = l2->next;
        else//将相同的元素,提取出来
        {
            if(head == NULL) head = l1, tail = head;
            else tail->next = l1, tail = tail->next;
            l1 = l1->next, l2 = l2->next;
        }
    }
    return head;
}
void Output(Node *l)
{
    if(l == NULL) printf("NULL");
    while(l)
    {
        printf("%d",l->data);
        if(l->next) printf(" ");
        l = l->next;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值