大一下 数据结构 清华严蔚敏(C语言)版 学习记录——链表

 多项式相加和相乘

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef int ElemType;
typedef int Status;
const int maxn=3000;
const ll INF=1e18;

//---------------------------------------结构体定义区-----------------------------------
/* typedef struct item
{
    int expn;//定义数据域的数据类型
}ElemType; */

typedef struct{
   float coef;//系数
   int expn;//指数
}term;

typedef struct Lnode//定义结点
{
    term data;//数据域
    struct Lnode *next;//指针域
}LNode,*LinkList;//将这个类型命名为LNode,并定义一个指向这个类型的指针

//----------------------------------------函数声明区------------------------------------
void CreateList_L(LinkList &L,int n);//头插法创建链表
void creatlist(LinkList &L,int n);//尾插法创建链表
void Creatpolyn(LinkList &L, int a);//创建多项式
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc);//链表的合并
void Orderinsertmerge(LinkList &L, term e);//按顺序插入项
void printpolyn(LinkList p);//打印多项式
void add(LinkList L1, LinkList L2, LinkList &L3);//多项式加法,结果以L3返回
void mult(LinkList L1,LinkList L2,LinkList &L4);//多项式乘法,结果以L4返回
void List(LinkList L); //打印链表
Status GetElem_L(LinkList L,int i,ElemType &e);//查找第i个元素并返回
Status ListInsert_L(LinkList&L,int i,ElemType e);//前插法:在带头结点的单链线性表L中第i个位置之前插入元素e
Status ListDelete_L(LinkList &L,int i,ElemType &e);//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值

//---------------------------------------函数定义区--------------------------------------
/*int ListInsert_L(LinkList &L,int i,ElemType e)
{ //在头结点的单链线性表L的第i个元素之前插入元素e
   if(!LocatePos(L,i-1,h)) return 0;//i值不合法
   if(!MakeNode(s,e)) return 0;//结点储存分配失败
   InsFirst(h,s);//对于从第i哥结点开始的链表,第i-1个结点是它的头结点
   return 0;
}*/

/*int MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc,int (*compare)(ElemType,ElemType))
{//La、Lb和Lc都是非递减序列
   if(!InitList(Lc)) return 0;//储存空间分配失败
   LinkList ha,hb;
   ha=GetHead(La);hb=GetHead(Lb);//ha和hb分别指向La和Lb的头结点
   pa=NextPos(La,ha),pb=NextPos(Lb,hb);//pa和pb分别指向La和Lb中当前结点
   while(pa&pb)
   {
      a=GetCurElem(pa);b=GetCurElem(pb);//a、b为两表中当前比较元素
      if((*compare)(a,b)<=0)
      {
         DelFirst(ha,q);Append(Lc,q);pa=NextPos(La,ha);
      }else{
         DelFirst(hb,q);Append(Lc,q);pb=NextPos(Lb,hb);
      }
   }
   if(pa) Append(Lc,pa);//链接La中剩余结点
   else Append(Lc,pb);//链接Lb中剩余结点
   FreeNode(ha);FreeNode(hb);//释放两个头结点
   return 1;
}*/

/*void CreatPolyn(polynomail &p,int m)
{  //输入m项的系数和指数,建立表示一元多项式的有序链表P
   InitList(P);h=GetHead(P);
   e.coef=0.0;e.expn=-1;SetCurElem(h,e);//设置头结点的数据元素
   for(int i=1;i<=m;i++)//依次输入m个非零项
   {
      scanf(e.coef,e.expn);
      if(!LocateElem(P,e,q,(*cmp)()))
      {  //当前链表中不存在该指数项
         if(MakeNode(s,e)) InsFirst(q,s);//生成结点并插入链表
      }
   }
}*/

/*void AddPolyn(polynomail &Pa,polynomail &Pb)
{//多项式加法;Pa=Pa+Pb,利用两个多项式的结点构成"和多项式"
   ha=GetHead(Pa);hb=GetHead(Pb);//ha和hb分别指向Pa和Pb的头结点
   qa=NextPos(Pa,ha);qb=NextPos(Pb,hb);//qa和qb分别指向Pa和Pb中当前结点
   while(qa&&qb)
   {
      a=GetCurElem(qa);b=GetCurElem(qb);//a和b为当前比较的元素
      switch (*cmp(a,b))
      {
         case -1://Pa指数小
         ha=qa;qa=NextPos(Pa,qa);break;
         case 0://二者的指数值相等
         sum=a.coef+b.coef;
         if(sum!=0.0)
         {//修改多项式Pa中当前结点的系数值
            SetCurElem(qa,sum);ha=qa;
         }else{//删除多项式Pa中当前结点
            DelFirst(ha,pa);FreeNode(qb);qb=NextPos(Pb,hb);
            qa=NextPos(Pa,ha);break;
         }
         case 1://Pb指小
         DelFirst(hb,qb);InsFirst(ha,qb);
         qb=NextPos(Pb,hb);ha=NextPos(Pa,ha);break;
      }
   }
   if(!ListEmpty(Pb)) Append(Pa,qb);//链接Pb中剩余结点
   FreeNode(hb);//释放Pb的头结点
}*/

/* void CreateList_L(LinkList &L,int n)//头插法
{   //逆位序输入n个元素的值,建立带表头结点的单链线性表L
    L=(LinkList)malloc(sizeof(Lnode));
    LinkList p;
    L->next=NULL;//先建立一个带头结点的单链表
    for(int i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));//生成新结点
        scanf("%d",&p->data);//输入元素值
        p->next=L->next;L->next=p;//插入到表头
    }
} */

/* void creatlist(LinkList &L,int n)//尾插法
{   //尾插法创建链表
    L=(LinkList)malloc(sizeof(Lnode));
    LinkList p,r=NULL;//它们的类型都是指针
    L->next=NULL;
    for(int i=0;i<n;++i)
    {
        p=(LinkList)malloc(sizeof(Lnode));
        //强制类型转换是指针,大小是结构体
        scanf("%d",&p->data);
        p->next=NULL;
        if(L->next==NULL) L->next=p;
        else r->next=p;//链接新创建的结点
        r=p;//r的指向在不断改变
    }
}  */

/* Status GetElem_L(LinkList L,int i,ElemType &e)
{
    //L是带头节点的单链表的头指针
    //当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
    LinkList p=L->next;int j=1;//初始化,p指向第一个结点,j为计数器
    while(p&&j<i)
    {   //顺指针向后查找,直到p指向第i个元素或p为空
        p=p->next;++j;
    }
    if(!p||j>i)return 0;//遍历完发现第i个元素不存在
    e=p->data;//取第i个元素
    return 1;
} */

/* Status ListInsert_L(LinkList&L,int i,ElemType e)
{   //前插法:在带头结点的单链线性表L中第i个位置之前插入元素e
    LinkList p=L;int j=0;//P为头结点,j为计数器
    LinkList s;
    while(p&&j<i-1)
    {   //寻找第i-1个结点
        p=p->next;++j;
    }
    if(!p||j>i-1) return 0;//i<1或者大于表长加1
    s=(LinkList)malloc(sizeof(Lnode));//生成指向新结点的指针
    s->data=e;s->next=p->next;//插入L中
    p->next=s;
    return 1;
} */

/* Status ListDelete_L(LinkList &L,int i,ElemType &e)
{   //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
    LinkList p=L;int j=0;
    LinkList q; q=(LinkList)malloc(sizeof(Lnode));
    while(p->next&&j<i-1)
    {   //寻找第i个结点,并令p指向其前驱
        p=p->next;++j;
    }
    if(!(p->next)||j>i-1) return 0;//删除位置不合理
    q=p->next;p->next=q->next;//删除q结点,并释放
    e=q->data;free(q);
    return 1;
} */

/* void MergeList_Sq(SqList LA,SqList LB,SqList &LC){ 
    pa = LA.elem;  
    pb = LB.elem;     //指针pa和pb的初值分别指向两个表的第一个元素 
    LC.length = LA.length+LB.length;      	//新表长度为待合并两表的长度之和 
    LC.elem = new ElemType[LC.length];    	//为合并后的新表分配一个数组空间 
    pc = LC.elem;                         		//指针pc指向新表的第一个元素 
    pa_last = LA.elem+LA.length-1; 	//指针pa_last指向LA表的最后一个元素 
    pb_last = LB.elem+LB.length-1; 	//指针pb_last指向LB表的最后一个元素 
    while(pa <= pa_last && pb <= pb_last){  	//两个表都非空 
        if(*pa <= *pb) *pc++ = *pa++;        	//依次“摘取”两表中值较小的结点      
        else *pc++ = *pb++;   
    } 
    //此时a,b 之中一定有一个表为空
    while(pb <= pb_last)  *pc++ = *pb++;          //LB表已到达表尾
    while(pa <= pa_last)  *pc++ = *pa++;          //LA表已到达表尾 
} */

/* void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
    //已知单链线性表La和Lb的元素按值非递减排列
    //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
    LinkList pa,pb,pc;
    pa=La->next;  pb=Lb->next;
    Lc=pc=La;                    //用La的头结点作为Lc的头结点 
    while(pa && pb){
      if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;}
      else{pc->next=pb; pc=pb; pb=pb->next;}
   }  
   pc->next=pa?pa:pb;//插入剩余段
   //若pa不空,则pc->next = pa;,否则则为pc->next = pb;
   free(Lb);//释放Lb的头结点
} */

/* void List(LinkList L)
{   //打印链表
    LinkList p;
    p=(LinkList)malloc(sizeof(Lnode));
    //if(L->data) p=L;//没有头结点的链表
    //else p=L->next;//有头结点的链表 
    p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
} */

void Creatpolyn(LinkList &L, int a)//创建多项式
{
    L = (LinkList)malloc(sizeof(Lnode));
    L->next = NULL;//建立头结点
    term e;
    for (int i = 1; i <= a; i++)
    {
        scanf("%f%d", &e.coef, &e.expn);
        Orderinsertmerge(L, e);//将所读得的数据插入链表
    }
}

void Orderinsertmerge(LinkList &L, term e)//按次数大小插入项(次数决定插入的位置)
{
    LinkList p, q;//q为操作指针,p指针指向q的下一位以方便排序
    p = L;//每次p都从头开始
    LinkList o = (LinkList)malloc(sizeof(Lnode));//o为临时节点
    while (p)//如果p=NULL,则跳出循环,在顺序表末尾添加结点
    {
        q = p;//通过循环移动指针q的位置
        p = p->next;//将p指向NULL
        if (e.coef == 0) return;//系数为0则直接返回该函数
        if (q->data.expn == e.expn)//次数相等则系数相加
        {
            q->data.coef += e.coef;
            return;
        }
        if (p && p->data.expn > e.expn)
        {   //若比当前结点小,就插到当前结点的前面
            o->data = e;
            q->next = o;
            o->next = p;
            return;
        }
        //若比当前结点大,p指针不断后移,直至变为NULL跳出循环
        //然后再插入链表,成为末尾结点
    }
    o->data = e;
    q->next = o;
    o->next = NULL;//临时节点的指针域指向null,成为末尾结点
}

void add(LinkList L1, LinkList L2, LinkList &L3)//多项式加法,结果以L3返回
{
    L3 = (LinkList)malloc(sizeof(Lnode));//建立头结点
    L3->next = NULL;
    LinkList q = L1->next;//指向L1的头结点的下一节点
    while (q)
    {
        Orderinsertmerge(L3, q->data);//插入至L3
        q = q->next;
    }
    q = L2->next;//指向L2的头结点的下一节点
    while (q)
    {
        Orderinsertmerge(L3, q->data);
        q = q->next;
    }
}

void mult(LinkList L1,LinkList L2,LinkList &L4)//多项式乘法,结果以L4返回
{
    L4 = (LinkList)malloc(sizeof(Lnode));//建立头结点
    L4->next = NULL;
    term e;//储存相乘后的结果
    LinkList p,q;
    p=L1->next;//p指向L1的第一个结点
    q=L2->next;//q指向L2的第一个结点
    while(p)
    {
        while(q)
        {
            e.coef=p->data.coef*q->data.coef;//系数相乘
            e.expn=p->data.expn+q->data.expn;//次数相加
            Orderinsertmerge(L4, e);
            q=q->next;
        }
        p=p->next;
        q=L2->next;//q重新遍历L2
    }
}

void printpolyn(LinkList p)//输出多项式
{
    LinkList q = p->next;//从头结点的下一结点开始
    while (q)
    {
        if (q->data.coef == 0)//如果系数为0,则不打印该项(加法会导致存在系数为零的项,不打印比删除方便)
        {
            q = q->next;
            continue;
        }
        printf("%.0f", q->data.coef);//先输出系数
        if (q->data.expn != 0)//如果次数不为零再输出,防止输出x^0
            printf(" %d\n", q->data.expn);
        q = q->next;//指向下一项
    }
}

//--------------------------------------主函数区--------------------------------------
int main(){
    LinkList L1, L2, L3,L4;
    int n;scanf("%d", &n);
    Creatpolyn(L1, n);
    scanf("%d", &n);
    Creatpolyn(L2, n);
    add(L1, L2, L3);
    mult(L1, L2, L4);
    printf("\nL1+L2=\n");
    printpolyn(L3);
    printf("\nL1*L2=\n");
    printpolyn(L4);
    return 0;
}

将La和Lb合并成Lc,并输出Lc中奇数项的和sum

#include<bits/stdc++.h>
#define Status int
using namespace std;
typedef long long ll;
typedef int ElemType;
const int maxn=3000;
const ll INF=1e18;


/* typedef struct item
{
    int expn;//定义数据域的数据类型
}ElemType; */

typedef struct Lnode//定义结点
{
    ElemType data;//数据域
    struct Lnode *next;//指针域
}LNode,*LinkList;//将这个类型命名为LNode,并定义一个指向这个类型的指针

void CreateList_L(LinkList &L,int n)//头插法
{   //逆位序输入n个元素的值,建立带表头结点的单链线性表L
    L=(LinkList)malloc(sizeof(Lnode));
    LinkList p;
    L->next=NULL;//先建立一个带头结点的单链表
    for(int i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));//生成新结点
        scanf("%d",&p->data);//输入元素值
        p->next=L->next;L->next=p;//插入到表头
    }
}

void creatlist(LinkList &L,int n)
{   //尾插法创建链表
    L=(LinkList)malloc(sizeof(Lnode));
    LinkList p,r=NULL;//它们的类型都是指针
    L->next=NULL;
    for(int i=0;i<n;++i)
    {
        p=(LinkList)malloc(sizeof(Lnode));
        //强制类型转换是指针,大小是结构体
        scanf("%d",&p->data);
        p->next=NULL;
        if(L->next==NULL) L->next=p;
        else r->next=p;//链接新创建的结点
        r=p;//r的指向在不断改变
    }
} 

Status GetElem_L(LinkList L,int i,ElemType &e)
{
    //L是带头节点的单链表的头指针
    //当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
    LinkList p=L->next;int j=1;//初始化,p指向第一个结点,j为计数器
    while(p&&j<i)
    {   //顺指针向后查找,直到p指向第i个元素或p为空
        p=p->next;++j;
    }
    if(!p||j>i)return 0;//遍历完发现第i个元素不存在
    e=p->data;//取第i个元素
    return 1;
}

Status ListInsert_L(LinkList&L,int i,ElemType e)
{   //前插法:在带头结点的单链线性表L中第i个位置之前插入元素e
    LinkList p=L;int j=0;//P为头结点,j为计数器
    LinkList s;
    while(p&&j<i-1)
    {   //寻找第i-1个结点
        p=p->next;++j;
    }
    if(!p||j>i-1) return 0;//i<1或者大于表长加1
    s=(LinkList)malloc(sizeof(Lnode));//生成指向新结点的指针
    s->data=e;s->next=p->next;//插入L中
    p->next=s;
    return 1;
}

Status ListDelete_L(LinkList &L,int i,ElemType &e)
{   //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
    LinkList p=L;int j=0;
    LinkList q; q=(LinkList)malloc(sizeof(Lnode));
    while(p->next&&j<i-1)
    {   //寻找第i个结点,并令p指向其前驱
        p=p->next;++j;
    }
    if(!(p->next)||j>i-1) return 0;//删除位置不合理
    q=p->next;p->next=q->next;//删除q结点,并释放
    e=q->data;free(q);
    return 1;
}

/* void MergeList_Sq(SqList LA,SqList LB,SqList &LC){ 
    pa = LA.elem;  
    pb = LB.elem;     //指针pa和pb的初值分别指向两个表的第一个元素 
    LC.length = LA.length+LB.length;      	//新表长度为待合并两表的长度之和 
    LC.elem = new ElemType[LC.length];    	//为合并后的新表分配一个数组空间 
    pc = LC.elem;                         		//指针pc指向新表的第一个元素 
    pa_last = LA.elem+LA.length-1; 	//指针pa_last指向LA表的最后一个元素 
    pb_last = LB.elem+LB.length-1; 	//指针pb_last指向LB表的最后一个元素 
    while(pa <= pa_last && pb <= pb_last){  	//两个表都非空 
        if(*pa <= *pb) *pc++ = *pa++;        	//依次“摘取”两表中值较小的结点      
        else *pc++ = *pb++;   
    } 
    //此时a,b 之中一定有一个表为空
    while(pb <= pb_last)  *pc++ = *pb++;          //LB表已到达表尾
    while(pa <= pa_last)  *pc++ = *pa++;          //LA表已到达表尾 
} */


void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
    //已知单链线性表La和Lb的元素按值非递减排列
    //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
    LinkList pa,pb,pc;
    pa=La->next;  pb=Lb->next;
    Lc=pc=La;                    //用La的头结点作为Lc的头结点 
    while(pa && pb){
      if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;}
      else{pc->next=pb; pc=pb; pb=pb->next;}
   }  
   pc->next=pa?pa:pb;//插入剩余段
   //若pa不空,则pc->next = pa;,否则则为pc->next = pb;
   free(Lb);//释放Lb的头结点
}

void List(LinkList L)
{   //打印链表
    LinkList p;
	int cnt=1,sum=0;
    p=(LinkList)malloc(sizeof(Lnode));
    /* if(L->data) p=L;//没有头结点的链表
    else p=L->next;//有头结点的链表 */
    p=L->next;
    while(p)
    {
        printf("%d ",p->data);
		if(cnt++%2==1) sum+=p->data;
        p=p->next;
    }
	printf("\n%d\n",sum);
}

int main(){
    LinkList La,Lb,Lc;
    int n1,n2;
    scanf("%d",&n1);
	scanf("%d",&n2);
    creatlist(La,n1);
    //List(La);
    creatlist(Lb,n2);
    //List(Lb);
    MergeList_L(La,Lb,Lc);
    List(Lc);
    return 0;
}

单链表的逆转求和

#include<stdio.h>
#include<stdlib.h>
#define  OK  1
#define  OVERFLOW  -2
typedef  int  ElemType; 
typedef  int  status;
typedef  struct  Lnode
{
	ElemType  data;
	struct  Lnode *next;
}Lnode,*linklist;
int sum=0;
status listcreate(linklist &L)
{
	linklist p,endl;
	int n;
	L=(linklist)malloc(sizeof(Lnode));
	if(!L)exit(OVERFLOW);
	L->next=NULL;//链表的初始化 
	endl=L;
	sum=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		p=(linklist)malloc(sizeof(Lnode));
		if(!p) exit(OVERFLOW);
		scanf("%d",&p->data);
		sum+=p->data;
		p->next=NULL;
		endl->next=p;
		endl=p;
	}
	return   OK;//返回建立完成 
}

void listoutput(linklist L)
{
	L=L->next;
	while(L)
	{
		printf("%d ",L->data);
		L=L->next;
	}
	//return   OK;
}

status reverse_list(linklist &L)
{
	linklist p,q,s=NULL;
	if(!L->next)return OK;//如果链表为空的话,直接返回 
	p=L->next;
	q=p->next;
	if(q) s=q->next;//如果q存在的话,s就指向q的下一个节点
	p->next=NULL;
	while(s)//跳出条件是s是否为空 
	{ 
		q->next=p;
		p=q;
		q=s;
		s=q->next;
	 } 
	if(q)
	{
		q->next=p;
		L->next=q;
	}
	 
}


int main()
{
	linklist L;
	listcreate(L);
	reverse_list(L);
	listoutput(L);
	printf("\n%d\n",sum);
	return 0;
 } 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

goodlunatic

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值