线性结构---链表

来源:互联网 发布:建立数据系统技术 编辑:程序博客网 时间:2024/06/05 16:02

链表


一元多项式求导   (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;elsetail->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 03 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 15 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 -12 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 -12 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 0