/*
实验一:线性表的基本运算
1.掌握线性表的顺序存储和链式存储这两种基本存储结构及其应用场合。
2.掌握顺序表和链表的各种基本操作算法。
3.理解线性表应用于多项式的实现算法。
*/
#include<stdio.h>
#include<stdlib.h>
#define ElemType int
////////////////////////////*线性表的顺序存储*////////////////////////////
//线性表的顺序表示定义
typedef struct seqList{
int n;//当前数据元素的个数
int maxLength;//线性表允许的最大长度
ElemType *element;//首地址
}SeqList;
//顺序表的初始化
int InitSeq(SeqList *L,int mSize){
L->maxLength=mSize;//从形参中获取线性表的最大长度
L->n=0;
L->element=(ElemType *)malloc(sizeof(ElemType)*mSize);//动态生成一维数组空间
//注:malloc函数返回的是指针(即开辟好的空间的首地址)
if(!L->element)//等价于if(L->element==NULL)
return 0;
return 1;
}
//顺序表的查找 O(1)的时间复杂度
int FindSeq(SeqList L,int i,ElemType *x){
if(i<0||i>L.n-1)
return 0;
*x=L.element[i];
return 1;
}
//顺序表的元素插入 O(n)的时间复杂度
int InsertSeq(SeqList *L,int i,ElemType x){
int j;
if(i<-1||i>L->n-1)
return 0;
if(L->n==L->maxLength)
return 0;
for(j=L->n-1;j>i;j++)//从后往前逐个后移元素
L->element[j+1]=L->element[j];
L->element[i+1]=x;
L->n++;
return 1;
}
//顺序表的元素删除 O(n)的时间复杂度
int DeleteSeq(SeqList *L,int i){
int j;
if(i<0||i>L->n-1)
return 0;
if(!L->n)//等价于if(L->n==NULL)即L为空
return 0;
for(j=i+1;j<L->n;j++)//从后往前逐个前移元素
L->element[j-1]=L->element[j];
L->n--;
return 1;
}
//顺序表的输出 O(n)的时间复杂度
int OutputSeq(SeqList *L){
int i;
if(L->n==0)
return 0;
for(i=0;i<=L->n-1;i++)
printf("%d ",L->element[i]);
printf("\n");
return 1;
}
//顺序表的撤销
void DestroySeq(SeqList *L){
L->n=0;
L->maxLength=0;
free(L->element);
}
void Seq(SeqList list){
if(InitSeq(&list,10)==0)return;//初始化线性表 设置10为线性表的最大长度
for(int i=0;i<10;i++){
if(InsertSeq(&list,i-1,i)==0)return;//插入0-9十个元素
}
printf("输出顺序表中的元素:");
if(OutputSeq(&list)==0)return;
printf("\n");
printf("输出顺序表中下标为3的数:");
int x;
if(FindSeq(list,3,&x)==0)return;
printf("%d\n\n",x);
if(DeleteSeq(&list,0)==0)return;//删除0
printf("输出删除0后顺序表中的元素:");
if(OutputSeq(&list)==0)return;
printf("\n");
DestroySeq(&list);
}
////////////////////////////*线性表的链式存储*////////////////////////////
typedef struct node{
ElemType element;//数据域
struct node *link;//指针域
}Node;
typedef struct headerList{//带表头结点
Node *head;
int n;
}HeaderList;
//单链表的初始化
int InitLinked(HeaderList *L){
L->head=(Node*)malloc(sizeof(Node));
if(!L->head)
return 0;
L->head->link=NULL;
L->n=0;
return 1;
}
//单链表的查找
int FindLinked(HeaderList L,int i,ElemType *x){
Node *p;
int j;
if(i<0||i>L.n-1)
return 0;
p=L.head;
for(j=0;j<i;j++)
p=p->link;
*x=p->element;
return 1;
}
//单链表的插入
int InsertLinked(HeaderList *L,int i,ElemType x){
Node *p,*q;
int j;
if(i<-1||i>L->n-1)
return 0;
p=L->head;
for(j=0;j<=i;j++)//从头结点开始查找ai
p=p->link;
q=(Node*)malloc(sizeof(Node));//生成新结点
q->element=x;
q->link=p->link;
p->link=q;
L->n++;
return 1;
}
//单链表的删除
int DeleteLinked(HeaderList *L,int i){
Node *p,*q;
int j;
if(!L->n)
return 0;
if(i<0||i>L->n-1)
return 0;
q=L->head;
for(j=0;j<i-1;j++)//从头结点开始查找ai
q=q->link;
p=q->link;
q->link=p->link;
free(p);
L->n--;
return 1;
}
//单链表的输出
int OutputLinked(HeaderList *L){
Node *p;
if(!L->n)
return 0;
p=L->head->link;
while(p){
printf("%d ",p->element);
p=p->link;
}
return 1;
}
//单链表的撤销
void DestroyLinked(HeaderList *L){
Node *p;
while (L->head)
{
p=L->head->link;//保存后继结点地址,防止断链4
free(L->head);
L->head=p;
}
}
void Linked(HeaderList list){
if(InitLinked(&list)==0)return;//初始化带表头的链表
for(int i=0;i<10;i++){
if(InsertLinked(&list,i-1,i)==0)return;//插入0-9十个元素
}
printf("输出链表中的元素:");
if(OutputLinked(&list)==0)return;
printf("\n\n");
printf("输出链表中第三个数:");
int x;
if(FindLinked(list,3,&x)==0)return;
printf("%d\n\n",x);
if(DeleteLinked(&list,0)==0)return;//删除0
printf("输出删除0后链表中的元素:");
if(OutputLinked(&list)==0)return;
printf("\n\n");
DestroyLinked(&list);
}
////////////////////////////*一元多项式*////////////////////////////
typedef struct pNode{
int coef;//系数
int exp;//指数
struct pNode* link;
}pNode;
typedef struct {
struct pNode *head;
}polynominal;//多项式
int a[100]={0};
int amax;
int b[100]={0};
int bmax;
int ti[100]={0};
void print(polynominal *p){//一元多项式的输出
pNode *q;
if(p->head==NULL)return;
q=p->head->link;
while(q!=NULL){
if(q->coef==0){
q=q->link;
continue;
}
if(q->exp==0)
printf("%d",q->coef);
else
printf("%dx^%d",q->coef,q->exp);
if(q->link!=NULL){
printf("+");
}
q=q->link;
}
}
void insert(polynominal *po,pNode *q){
pNode *t,*p;
p=po->head;
t=(pNode*)malloc(sizeof(pNode));
while(p->link!=NULL){//从头结点开始寻找插入的位置
//printf("p->exp=%d,q->exp=%d\n",p->exp,q->exp);//调试
if(p->exp>=q->exp)break;
else if(p->exp<q->exp){
t=p;
p=p->link;
if(p->exp>q->exp){
p=t;
break;}
}
}
// printf("p->exp=%d,q->exp=%d\n",p->exp,q->exp);//调试
if(p->exp==q->exp){
p->coef+=q->coef;
}
else{
q->link=p->link;
p->link=q;
}
}
void init(polynominal *po,int x){//一元多项式的创建&输入
pNode *q,*p,*t;
p=(pNode*)malloc(sizeof(pNode));
//初始化po头结点
p->coef=0;
p->exp=-1;
p->link=NULL;
po->head=p;
int flag=1;
int i=1;
printf("请输入第%d个多项式:\n",x);
while(flag){
q=(pNode*)malloc(sizeof(pNode));
printf("请输入第%d个多项式第%d项的系数:",x,i);
scanf("%d",&q->coef);
printf("请输入第%d个多项式第%d项的指数:",x,i);
scanf("%d",&q->exp);
i++;
insert(po,q);
printf("您目前的输入为:");
print(po);
printf("\n您是否需要继续输入,需要请输入1,不需要请输入0:");
scanf("%d",&flag);
}
}
/*法1:借助数组来实现一元多项式的加法和乘法*/
int max(int a,int b){
if(a>=b)return a;
else return b;
}
void pre(polynominal *p1,polynominal *p2){//加法和乘法前的预处理
pNode *q;
amax=0;
bmax=0;
if(p1->head!=NULL){
q=p1->head->link;
while(q!=NULL){
a[q->exp]+=q->coef;
amax=max(amax,q->exp);
q=q->link;
}
}
// printf("%d\n",pmax);
if(p2->head!=NULL){
q=p2->head->link;
while(q!=NULL){
b[q->exp]+=q->coef;
bmax=max(bmax,q->exp);
q=q->link;}
}
// printf("%d\n",pmax);
}
//多项式的加法p1+p2=p3
void plus1(polynominal *p1,polynominal *p2,polynominal *p3){
pNode *q,*p,*t;
p=(pNode*)malloc(sizeof(pNode));
p->coef=0;
p->exp=-1;
p->link=NULL;
p3->head=p;
// printf("%d %d\n",amax,bmax);
int pmax=max(amax,bmax);
for(int i=0;i<=pmax;i++){
if(a[i]+b[i]==0)continue;
q=(pNode*)malloc(sizeof(pNode));
q->exp=i;
q->coef=a[i]+b[i];
p->link=q;
p=p->link;
}
p->link=NULL;
}
//多项式的乘法p1*p2=p4
void time1(polynominal *p1,polynominal *p2,polynominal *p4){
pNode *q,*p,*t;
p=(pNode*)malloc(sizeof(pNode));
p->coef=0;
p->exp=-1;
p->link=NULL;
p4->head=p;
int pmax=0;
for(int i=0;i<=amax;i++){
for(int j=0;j<=bmax;j++){
ti[i+j]+=a[i]*b[j];
pmax=max(pmax,i+j);
// printf("%d %d %d %d\n",a[i],b[j],ti[i+j],i+j);
}
}
for(int i=0;i<=pmax;i++){
q=(pNode*)malloc(sizeof(pNode));
q->exp=i;
q->coef=ti[i];
p->link=q;
p=p->link;
}
p->link=NULL;
}
/*法2:直接使用链表来实现一元多项式的加法和乘法*/
void plus2(polynominal *p1,polynominal *p2,polynominal *p3){
pNode *q,*p,*t,*a,*b;
p=(pNode*)malloc(sizeof(pNode));
t=(pNode*)malloc(sizeof(pNode));
a=p1->head;
b=p2->head;
//初始化p3头结点
p->coef=0;
p->exp=-1;
p->link=NULL;
p3->head=p;
int flag=1;
while(!(a==NULL&&b==NULL)){
q=(pNode*)malloc(sizeof(pNode));
if(a==NULL){
q->coef=b->coef;
q->exp=b->exp;
b=b->link;
}
else if(b==NULL){
q->coef=a->coef;
q->exp=a->exp;
a=a->link;
}
else if(a->exp==b->exp){
q->coef=a->coef+b->coef;
q->exp=a->exp;
a=a->link;
b=b->link;
}
else if(a->exp<b->exp){
q->coef=a->coef;
q->exp=a->exp;
a=a->link;
}
else {
q->coef=b->coef;
q->exp=b->exp;
b=b->link;
}
insert(p3,q);
}
}
void time2(polynominal *p1,polynominal *p2,polynominal *p4){
pNode *q,*p,*a,*b;
p=(pNode*)malloc(sizeof(pNode));
a=p1->head;
b=p2->head;
//初始化p4头结点
p->coef=0;
p->exp=-1;
p->link=NULL;
p4->head=p;
int flag=1;
while(a!=NULL){
b=p2->head;
while(b!=NULL){
q=(pNode*)malloc(sizeof(pNode));
q->coef=a->coef*b->coef;
q->exp=a->exp+b->exp;
insert(p4,q);
b=b->link;
}
a=a->link;
}
}
//多项式的撤销
void destroy(polynominal *l){
pNode *p;
while (l->head)
{
p=l->head->link;//保存后继结点地址,防止断链4
free(l->head);
l->head=p;
}
}
void poly(polynominal p1,polynominal p2,polynominal p3,polynominal p4){
//初始化多项式p1,p2
init(&p1,1);
init(&p2,2);
printf("第一个多项式为:");
print(&p1);
printf("\n");
printf("第二个多项式为:");
print(&p2);
printf("\n");
pre(&p1,&p2);//预处理
//将p1与p2相加,和存储到p3
plus2(&p1,&p2,&p3);
printf("它们的和为:");
print(&p3);
printf("\n");
//将p1与p2相乘,积存储到p4
time2(&p1,&p2,&p4);
printf("它们的积为:");
print(&p4);
//撤销p1和p2
destroy(&p1);
destroy(&p2);
}
int main(){
//顺序表的相关操作:初始化、查找、插入、删除、输出、撤销 以插入0-9为例
SeqList list;
Seq(list);
//带表头结点的链表的相关操作:初始化、查找、插入、删除、输出、撤销 以插入0-9为例
HeaderList list2;
Linked(list2);
//多项式的相关操作:一元多项式的创建、输出、撤销以及两个一元多项式相加和相乘
polynominal p1,p2,p3,p4;
poly(p1,p2,p3,p4);
return 0;
}