数据结构:链表练习题

214 阅读4分钟

一元多项式计算

分析题目

两种存储方法:

  1. 只存储各项系数,存储位置下标就可以对应指数值,适用于非零项系数多的(也就是不稀疏)
  2. 系数和指数均存入顺序表,适用于零项很多,指数较大(一个一个算指数太慢)

结点结构

多项式<--->polynomial

typedef struct Polynode{
	int coef;		//系数
    int exp;		//指数
    struct Node *next;
}Polynode,*Polylist;

创建一元多项式

采用尾插法依次插入系数和指数,思想不再赘述

Polylist CreatPoly(){	//尾插法,多项式创建函数 
	Polynode *head,*rear,*s;
	int a,b;		//分别为系数和指数 
	head=(Polynode*)malloc(sizeof(Polynode));		//申请一个头结点 
	rear=head;		//尾结点连上头结点 
	printf("输入系数和指数,逗号分隔,系数输入“99999”结束输入\n");
	scanf("%d,%d",&a,&b);		//首次输入,a为系数,b为指数 
	
	while(a!=99999)			//当系数为99999时结束输入多项式 
	{
		s=(Polynode*)malloc(sizeof(Polynode));
		s->coef=a;
		s->exp=b;
		rear->next=s;		//尾指针指向新结点 
		rear=s;
		scanf("%d,%d",&a,&b);
	}
	
	rear->next=NULL;		//尾结点指向NULL 
	return head;		//返回头结点即可 
}

主体解读:首先输入两个值并判断是否结束,不结束的话就进入while循环,每次循环都重新赋值并检测是否结束。

两式相加

所加两式默认升幂排列(也可以冒泡排序成升幂)

  • p指向LA,q指向LB
  • 以LA为“和多项式”
  • 若p结点指数较小,则p后移
  • 若q结点指数较小,则q插入在p之前
  • 若p结点和q结点指数相同,则将系数相加。 和不为0时修改p结点,释放q结点;为0时删除p结点,释放p和q

最重要需要注意多次给tail->next赋值

#include<stdio.h>
#include<stdlib.h>

typedef struct Polynode{
	int coef;		//系数
	int exp;		//指数
	struct Polynode *next; 
}Polynode,*Polylist;

Polylist CreatPoly();	//多项式创建函数 
Polylist AddPoly(Polylist LA,Polylist LB);	//将LA和lB两个多项式相加 


int main(){
	Polylist LA,LB;
	Polynode *p; 
	printf("输入第一个多项式\n");
	LA=CreatPoly();	
	printf("\n输入第二个多项式\n"); 
	LB=CreatPoly();	
	printf("\n\n两式输入结束\n\n");
	
	AddPoly(LA,LB);
	printf("\n");
	p=LA->next;

	while(p!=NULL){
		printf("%d,%d   ",p->coef,p->exp);
		p=p->next;
	}
}


Polylist CreatPoly(){	//尾插法,多项式创建函数 
	Polynode *head,*rear,*s;
	int a,b;		//分别为系数和指数 
	head=(Polynode*)malloc(sizeof(Polynode));		//申请一个头结点 
	rear=head;		//尾结点连上头结点 
	printf("输入系数和指数,空格分隔,系数输入“999”结束输入\n");
	scanf("%d %d",&a,&b);		//首次输入,a为系数,b为指数 
	
	while(a!=999)			//当系数为99999时结束输入多项式 
	{
		s=(Polynode*)malloc(sizeof(Polynode));
		s->coef=a;
		s->exp=b;
		rear->next=s;		//尾指针指向新结点 
		rear=s;
		scanf("%d %d",&a,&b);
	}
	
	rear->next=NULL;		//尾结点指向NULL 
	return head;		//返回头结点即可 
}

Polylist AddPoly(Polylist LA,Polylist LB){	//将LA和lB两个多项式相加 
	Polynode *p,*q,*tail,*temp;		
	//tail是“和多项式”的表尾指示器,temp是临时结点 
	int sum;		//系数和
	p=LA->next;		//指向首元 
	q=LB->next;
	while(p!=NULL&&q!=NULL)		//都没处理完 
	{
	/*每次都需要重新定位tail,因为系数和为0时候,tail所指结点会被销毁*/
		if(p->exp<q->exp)
		{	
			tail->next=p;		//定位tail 
			tail=p;				//表尾跟上p 
			p=p->next; 			//p后移 
			printf("下一个");
		}
		else if(p->exp==q->exp) 
		{
			sum=p->coef+q->coef;
			if(sum!=0)
			{
				p->coef=sum;	//修改数值 
				
				tail->next=p;	//定位tail	
				tail=p;			//表尾跟上p 
				p=p->next; 		//p后移 
				
				temp=q;			//需要释放q但不能丢了q 
				q=q->next;		//q全身而退 
				free(temp);		//temp成了替死鬼 
				printf("取代");
			}
			else 				//将p和q所指结点删除 
			{
				temp=p;			
				p=p->next;		 
				free(temp);
				temp=q;			 
				q=q->next;		 
				free(temp);	
				printf("双效");	
			} 
		}
		else if(p->exp>q->exp)
		{
			tail->next=q;
			tail=q;
			q=q->next; 
			printf("接上");
		}
		
		if(p!=NULL)
		{
			tail->next=p;
		}
		else
		{
			tail->next=q;
		}
	
	} 
	printf("加法运算完毕");
}

主体解读:本算法最后将“和多项式”在LA中体现。 若p结点指数较小,则tail跟上p,p后移;若两结点指数相同,;

若q结点指数较小,则q插入在p之前,让tail跟上q

若p结点和q结点指数相同,则将系数相加。 和不为0时修改p结点,释放q结点;为0时删除p结点,释放p和q

原地逆置单链表

所以我们需要将原链表在原有空间中,使用头插法

void ReverseList(LinkList L)
{
	p=L->next;		//定位首元结点	
    L->next=NULL;	//断掉头结点与原表关系
    while(p!=NULL)
    {
    	q=p->next;		//保留技术 
        p->next=L->next;
        L->next=p;
        p=q;
    }
}

二进制数加1

分析: 耿国华老师: www.bilibili.com/video/BV1kx…