数据结构-线性表-链式存储【链表】

2023年8月2日18:39:09

目的:学习测试

作者:wHappy

代码所需头文件define.h
# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>
# include "define.h"

/*
时间:2023年7月27日21:56:31
作者:wHappy
目的:研究链式存储(考研打基础)
内容:单链表 ,循环链表,双向链表

链表(链式存储结构)的特点
(1)结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻。
(2)访问时只能通过头指针进入链表)并通过每个结点的指针域依次向后顺序扫描其余结点,
    所以寻找第一个结点和最后一个结点所花费的时间不等

线性表的链式存储结构
·线性表中数据元素(结点)在存储器中的位置是任意的,
  即逻辑上相邻的数据元素在物理位置上不一定相邻。


  循环链表:首位相连构成的链表,从任意结点出都能找到表里的其他结点(从任意结点循环访问所有元素)

  双链表:有两个指针域,一个指向直接前驱,另一个指向指直接后继
*/

// #ifndef # define #endif 避免头文件重复利用
# ifndef _LINKLIST_H
# define _LINKLIST_H

//全局变量定义区
typedef int LIElemtype; //这里以最简单的数据域存储为整形int 为数据类型,也可以是很复杂的数据类型

//单链表结点
typedef struct _LNode //定义单链表结点类型
{
	LIElemtype data; //数据域
	struct _LNode* next; //指针域
}LNode, *LinkList; //LNode普通类型(.操作元素) *LinkList指针类型(->操作元素)

//双链表结点 
typedef int DouLElemtype;  //数据域复合数据类型,这里以简单数据类型int为例
typedef struct _DouLinkNode  //定义一个双链表结点类型
{
	DouLElemtype data; //数据域
	struct _DouLinkNode* prior; //指向前驱结点指针域 
	struct _DouLinkNode* next; //指向后继结点指针域
} DouLinkNode, *DouLinkList; 

//多项式结点类型
typedef struct _PolyNode
{
	int coeffcient ;//系数
	int exponent ;//指数
	struct _PolyNode* next; //指向后继结点指针
}PolyNode, *Polynomial;                  

//多项式基本操作
void InitPolynomial(Polynomial* p, int length); //初始化
void Traverse_P(Polynomial p);
void Print(Polynomial head); //输出多项式单链表
void AddPloynomial(Polynomial pa, Polynomial pb); //函数式相加
void AddPloynomial_1(Polynomial pa, Polynomial pb);//pa,pb分别为多项式一和多项式二的头指针

//单链表的基本操作
Status InitLL(LinkList* L); //初始化
LinkList CreateLL_H(LinkList &L, int n);//头插法创建链表
void CreateLL_R(LinkList L, int n);//尾插法创建链表
void Traverse(LinkList L);//遍历
Status Is_empty(LinkList L); //判空
Status ClearLL(LinkList* L);//清空单链表
Status Length_L(LinkList L); //单链表长度
Status GetElem(LinkList L, int position, LIElemtype* e); //获取元素(时间复杂度O(n))
Status LIInsertNode(LinkList L, int position, LIElemtype e);//插入 (时间复杂度O(n))
Status LIDeleteNode(LinkList L, int position, LIElemtype* e);//删除(时间复杂度O(n))
LinkList LocateElem_add(LinkList L, LIElemtype e);//按值查找 返回要查找的地址(时间复杂度O(n))
Status LocateElem_serial(LinkList L, LIElemtype e);//按值查找 返回计数器的值(时间复杂度O(n))
Status LIDestroy(LinkList *L);//销毁
LinkList BubbleSort(LinkList L);//冒泡排序
void Merge_LinkedList(LinkList *La, LinkList *Lb, LinkList *Lc);//有序合并三个链表
LinkList Create_list(void); //创建链表

//循环链表的操作
Status InitLL_cir(LinkList* L); //初始化循环链表
LinkList CreateLL_RC(LinkList L, int n); //尾插法创建循环单链表 王卓版
LinkList Connect_LC(LinkList La, LinkList Lb); //合并两个循环链表

//双向链表操作 两个指针域一个数据域,除了插入和删除区别于单链表其他都差不多
void InitDL(DouLinkList* L); //双链表的初始化
void CreateDL_H(DouLinkList L, int length);//创建双向链表 头插法
DouLinkList CreateDL_R(DouLinkList L, int length); //创建双向链表 尾插法
void TraverseDL_H(DouLinkList L);//前驱遍历双向链表
void TraverseDL_R(DouLinkList L);//后继遍历双向链表
DouLinkList GetElemDL(DouLinkList L, int position); //获取position-1位置(时间复杂度O(n))
Status InsertDL(DouLinkList L, int position, DouLElemtype e);//插入
void DeleteDL(DouLinkList L, int position,DouLElemtype* e);//删除 e:保留删除的元素

#endif


int main(void)
{
	/*
	//双链表验证
	int n,data,length;
	int len;
	DouLinkList L,T;
	InitDL(&L);//初始化双链表
    CreateDL_R(L, 5);//创建双向链表 头插法
	//InsertDL(L, 2, 99);//插入
	DeleteDL(L, 2,&data);//删除 e:保留删除的元素
	printf("删除的元素为%d\n",data);
	TraverseDL_R(L);//前驱遍历双向链表
	*/

/*
单链表操作验证
LinkList L;
	LinkList La,Lb; //定义一个单链表	
    InitLL_cir(&La);
	InitLL_cir(&Lb);
	La = CreateLL_RC(La, 3);
	Lb = CreateLL_RC(Lb, 4);
	L = Connect_LC(La, Lb);

*/	

/*
//验证单链表有序合并两链表
	LinkList La, Lb, Lc;
	//初始化三个链表
	InitLL(&La); 
	InitLL(&Lb);
	InitLL(&Lc);
	//尾插法创建两个单链表
	CreateLL_R(La,4);
	CreateLL_R(Lb,7);
    //有序合并La和Lb
	Merge_LinkedList(&La, &Lb, &Lc);
	Traverse(Lc);

	system("pause");

*/	

//多项式相加算法验算
	Polynomial L1,L2;
	InitPolynomial(&L1, 2);
	InitPolynomial(&L2, 1);
    AddPloynomial(L1, L2);
	Print(L1);

	//InitPolynomial(&L2, 1);
	//Traverse_P(L2);
    //L3 = AddPloynomial(L1, L2);
	//Traverse_P(L3);
  
	//Traverse(L);
	//Traverse(Lb);
	//Traverse(Lb);
	//L = create_list();
	//CreateLL_R(L, 5);
	//GetElem(L, 2,&data);//获取的的是position-1位置的data
	//printf("获取的元素:data = %d\n",data);
	//LIInsertNode(L, 2,  99);//插入
	//LIDeleteNode(L, 2, &data);//删除
	//printf("删除的元素:data = %d\n",data);
	//BubbleSort(L);//排序
	//len = Length_L(L);//链表长度
	//printf("len = %d\n",len);
	//ClearLL(&L);
	//CreateLL_H(L, 5);
	
	return 0;
}


//双链表基本操作

void InitDL(DouLinkList* L) // 双链表的初始化
{
	(*L) = (DouLinkList)malloc(sizeof(DouLinkNode)); //动态分配结点空间
	(*L)->next = NULL; //后继指针置空
	(*L)->prior =NULL; //前驱指针置空
}

void TraverseDL_H(DouLinkList L)//前驱遍历双向链表
{
	DouLinkList p = L;

	while(p)
	{
		printf("%d ",p->data);
		p = p->prior;
	}
	printf("\n");

}

void TraverseDL_R(DouLinkList L) //后继遍历双向链表
{
	DouLinkList p = L->next;
	while(p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}

void CreateDL_H(DouLinkList L, int length) //创建双向链表 头插法
{
	for (int i=0; i<length; i++)
	{
		DouLinkList pNew = (DouLinkList)malloc(sizeof(DouLinkNode)); //为新结点分配一块内存,pNew指针指向这块内存
		int data; //定义一个临时存放数据的变量
		printf("(for %d) Please input the data:",i+1);//提示用户输入第几个数据
		scanf("%d",&data); //输入数据
		pNew->data = data; //数据存入结点的数据域
		pNew->next = L->next; //新结点后继指针指向空
		pNew->prior = L; //新结点前驱指针指向头结点
		L->next = pNew; //头结点后继指向新结点
	}
}

DouLinkList CreateDL_R(DouLinkList L, int length) //创建双向链表 尾插法
{
	DouLinkList pTail = L ; //定义一个始终指向尾结点的指针pTail
	for (int i=0; i<length; i++)
	{
		DouLinkList pNew = (DouLinkList)malloc(sizeof(DouLinkNode)); //尾指针指向头结点
		int data;
		printf("(for %d) Please input the number:",i+1);
		scanf(" %d",&data);
		pNew->data = data; //第一步将数据存入数据域
		pNew->next = NULL; //第二步新结点指针域置空
		pNew->prior = pTail;//第三步新结点前驱指针指向尾指针指向的结点
		pTail->next = pNew;//第四步尾指针前驱指针指向新结点
		pTail = pNew;//第五步最后尾指针再指向最后一个结点

	}

	return pTail;
}

DouLinkList GetElemDL(DouLinkList L, int position) //获取元素(时间复杂度O(n))
{
	int i=0;
	while (L->next && i<position-1)
	{
		i++;
		L = L->next;
	}

	return L;
}

Status InsertDL(DouLinkList L, int position, DouLElemtype e)//插入
{
	DouLinkList p = L;
	
	p = GetElemDL(p, position); //找到position-1位置的p节点
	if( !p ) //没有找到异常处理
		return ERROR;
	else //找到进行插入操作
	{
		DouLinkList pNew = (DouLinkList)malloc(sizeof(DouLinkNode)); //pNew指向生成的新结点
		pNew->data = e; //数据存入数据域
		pNew->next = p->next; // 第一步 新结点的后继指向p结点的后继
		pNew->prior = p;//第二步 新结点的前驱指向p结点
		p->next = pNew; //p结点的后继结点指向新结点
		p->next->prior = pNew;//最后 p结点的后继结点的前驱指针指向新结点

	}
	return OK;
}

void DeleteDL(DouLinkList L, int position,DouLElemtype* e)//删除 e:保留删除的元素
{
	DouLinkList p=L; //p指向头结点
	p = GetElemDL(p,position); //函数作用找到position-1个结点,并将该节点返回
	if(!p) 
	{
		printf("位置不存在!\n");
		exit(-1);
	}	
	else
	{
		//删除操作
		DouLinkList pfree = p->next; //指向position位置的结点
		*e = pfree->data; //将删除结点的值保存下来
		p->next = p->next->next; //p结点的后继指针指向position+1位置的结点
		p->next->next->prior = p; //position+1位置的结点的前驱指针指向p结点
		free(pfree); //释放position位置的结点
		pfree = NULL; //释放的结点置空
	}
}


//单链表基本操作

Status InitLL(LinkList* L) //初始化单链表
{
	(*L) = (LinkList)malloc(sizeof(LNode)); //为链表动态分配空间 L是二级指针 *L是一级指针
	if((*L) == NULL) //异常处理
	{
		printf("分配失败!\n");
		exit(-1);
	}

	(*L)->next = NULL; //指针域置空
	
	return OK;
}

Status InitLL_cir(LinkList* L) //初始化循环链表
{
	(*L) = (LinkList)malloc(sizeof(LNode)); //为链表动态分配空间 L是二级指针 *L是一级指针
	if((*L) == NULL) //异常处理
	{
		printf("分配失败!\n");
		exit(-1);
	}

	(*L)->next = NULL; //指针域置空
	
	return OK;
}

Status Is_empty(LinkList L) //判空
{
	if(L)
		return 0; //非空
	else
		return 1;
}

Status LIDestroy(LinkList *L)//销毁
{
	if(!(*L))
		return ERROR; 
	LinkList p =*L; //指向第一个头结点

	while(p)
	{
		LinkList pfree = p;
		p = p->next; //此行和下行不能互换
		free(pfree);
		pfree = NULL;
	}
	*L = NULL;
		
	return OK;
}

Status ClearLL(LinkList* L) //清空单链表
{
	LinkList p,q; //定义两个指针
	p = (*L)->next; //p指向首结点

	while(p) //依次释放结点
	{
		q = p->next;
		free(p);
		p = q;
	}
	(*L)->next = NULL; //链表指针域置空

	return OK;
}

Status Length_L(LinkList L) //单链表长度
{
	LinkList p;
	p = L->next;
	int len = 0;

	while(p)
	{
		len++;
		p = p->next;
	}

	return len;
}

void Traverse(LinkList L)//遍历
{
	LinkList p = L->next; //定义一个指针p始终首先指向首结点

	while(p)
	{
		printf("%d ",p->data);
		p = p->next; //p接着指向下一个结点
	}
	printf("\n");

}

Status GetElem(LinkList L, int position, LIElemtype* e) //获取元素(时间复杂度O(n))
{
	LinkList p = L->next; //指向首结点
	int cnt = 1; //计数器记录当前p结点位置
	
	if(!p || position<cnt) //异常处理
		return ERROR;
	
	while(p && position>cnt) //当p不为空时,position==cnt说明找到该位置了
	{
		p->next;
		cnt++;
	}	
	*e = p->data;

	return OK;
}

LinkList LocateElem_add(LinkList L, LIElemtype e)//按值查找 返回要查找的地址(时间复杂度O(n))
{
	LinkList p = L->next;

	while(p && (p->data!=e))
		p = p->next;

	if(!p) //如果p不为空还没找到,p的地址就返回NULL
		return NULL;

	return p;
}

Status LocateElem_serial(LinkList L, LIElemtype e) //按值查找 返回计数器的值(时间复杂度O(n))
{
	LinkList p = L->next;
	int s = 1; //定义计数器记录的元素序号s

	while(p && (p->data!=e))
	{
		p = p->next;
		s++;
	}

	//循环结束之后两种情况
	if(p)  
		return s;
	else
		return 0;
}

Status LIInsertNode(LinkList L, int position, LIElemtype e)//插入 (时间复杂度O(n))
{
	LinkList q;
	LinkList p = L; //插入操作与GetElem操作不同
	int i = 0; //i从0开始,p要从L开始
	//因为如果从1到L的话,无法在插入1这个位置
	while(p && i<position-1)
	{
		i++;
		p = p->next;
	}

	//循环结束之后,又分为两种情况找到和没找到
	if(!p || i>position-1) //没找到
		return ERROR;

     //找到
#if 1 //方法1
	LinkList pNew = (LinkList)malloc(sizeof(LNode)); //分配新结点
	pNew->data = e;
	pNew->next = p->next;
	p->next = pNew;
#elif 0 //方法2
    LinkList pNew = (LinkList)malloc(sizeof(LNode)); //分配新结点
	pNew->data = e;
	q = p->next;
	p->next = pNew;
	pNew->next = q;
#endif

	return OK;
}

Status LIDeleteNode(LinkList L, int position, LIElemtype* e) //删除(时间复杂度O(n))
{

	LinkList p = L; //指向头结点
	int i = 0;
	
	while(p && i<position-1)
	{   //查找position-1位置结点地址
		p = p->next;
		i++;
	}
	//循环结束之后,又分为两种情况找到和没找到
	if(!p || !(p->next) || position-1<i)//没找到 
		return ERROR; //多增加一条语句!(p->next),意思是当节点数为n时,删除n+1个结点会error

	//找到 执行删除算法
	LinkList pfree = p->next; //定义一个指向要删除结点的指针
	*e = pfree->data; //将要删除结点的数据域保存下来
	p->next = pfree->next; //其次再将要删除结点的前驱指向其后继
	free(pfree); //最后释放其内存
	pfree = NULL;
	return OK;
	
}

LinkList CreateLL_H(LinkList &L, int n) //头插法创建链表 时间复杂程度O(n)
{ //此方法创建的链表,遍历的顺序和创建顺序相反
    L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	
	printf("Please input %d number:\n",n);
	
	for(int i=0; i<n; i++) //头插法
	{
		LinkList pNew = (LinkList)malloc(sizeof(LNode)); //分配一个新结点
		int data;
		printf("请输入第%d数据: ",i+1);
		scanf(" %d",&data); //输入一个数据
		pNew->data = data; //将数据存入新结点的数据域中
		pNew->next = L->next; //再将新结点指针域置空
		L->next = pNew; //最后将新结点接到头结点后面
	}


	return L;
}

LinkList Create_list(void) //创建链表(尾插法1)
{
	int len; //结点个数
	int i;
	int val; //用来临时存放用户输入的结点的值
	
	LinkList L = (LinkList)malloc(sizeof(LNode)); //动态生成一个头结点
	if(NULL == L) //判断是否生成头结点
	{
		printf("分配失败,程序终止!\n");
		exit(-1);
	}

	LinkList pTail = L; //定义一个始终指向尾结点的结构体指针变量
	pTail->next = NULL; //清空尾结点指针域使其始终指向链表最后一个结点

	printf("请输入你需要生成链表结点的个数:len = ");
	scanf("%d",&len);

	for(i=0; i<len; i++)//生成链表步骤
	{
		printf("请输入第%d个结点的值:",i+1);
		scanf("%d",&val);

		LinkList pNew = (LinkList)malloc(sizeof(LNode)); //生成的新结点
		if(NULL == pNew)
		{
			printf("分配失败,程序终止!\n");
			exit(-1);
		}

		//链表生成算法
		pNew->data = val;
		pTail->next = pNew;
		pNew->next = NULL;
		pTail = pNew;
		
	}

	return L; //返回链表的首地址(通过首地址能够找到整个链表)
}

LinkList CreateLL_RC(LinkList L, int n) //尾插法创建链表王卓版
{
	printf("Please input %d number:\n",n); //接收输入结点个数

	LinkList pTail = L; //定义一个尾指针始终指向我们的尾结点

	//链表生成算法
	for (int i=0; i<n; i++)
	{
		
		LinkList pNew = (LinkList)malloc(sizeof(LNode)); //动态分配一个结点
		int data; //定义一个存放数据变量
		printf("请输如第%d数据: ",i+1);
		scanf("%d",&data); //输入数据
		pNew->data = data; //存入数据到结点的数据域
		pNew->next =  L->next; //尾指针指针域置空
		pTail->next = pNew;  //尾指针的指针域指向新结点
		pTail = pNew; //最后移动尾指针也指向尾结点
			
	}
	return pTail;
}

void CreateLL_R(LinkList L, int n) //尾插法创建单链表王卓版
{
	printf("Please input %d number:",n); //接收输入结点个数
	
	LinkList pTail = L; //定义一个尾指针始终指向我们的尾结点

	//链表生成算法
	for (int i=0; i<n; i++)
	{
		LinkList pNew = (LinkList)malloc(sizeof(LNode)); //动态分配一个结点
		int data; //定义一个存放数据变量
		scanf(" %d",&data); //输入数据
		pNew->data = data; //存入数据到结点的数据域
		pNew->next =  NULL; //尾指针指针域置空
		pTail->next = pNew;  //尾指针的指针域指向新结点
		pTail = pNew; //最后移动尾指针也指向尾结点

	}
}

LinkList BubbleSort(LinkList L) //冒泡排序
{
	int i,j;
	int len = Length_L(L); //求链表的长度
	LinkList p, q; //定义两个指针

	//冒泡排序核,心算法
	for (i=0,p = L->next; i<len-1; i++,p = p->next) //n个数总体只需要比较n-1次
	{	
		for (j=i+1,q=p->next; j<len; j++,q = q->next) //内部要逐个比较也就是n次
		{		
			if(p->data > q->data)//升序
			{
				int temp; //用于交换的临时变量
				temp = p->data;
				p->data = q->data;
				q->data = temp;
			}
			
		}

	}
	
	return L;
}

LinkList Connect_LC(LinkList La, LinkList Lb) //合并两个循环链表
{
	LinkList p = (LinkList)malloc(sizeof(LNode));
	//四步
	p = La->next; //第一步p指向链表La的头结点
	La->next = Lb->next->next; //尾结点指向Lb的首结点
	free(Lb->next); //释放Lb的头结点
	Lb->next = p;

	return Lb;
}

void Merge_LinkedList(LinkList *La, LinkList *Lb, LinkList *Lc)//有序合并三个链表
{
	*Lc = *La; //Lc指向La的头结点,并使用La的头结点进行合并
	LinkList pa = (*La)->next; //定义两个指针变量pa,pb分别指向La和Lb的有首结点
	LinkList pb = (*Lb)->next;
	LinkList pc = (*Lc); //pc指向Lc头结点
	
	while (pa && pb) //pa和pb 不为空
	{
		if(pa->data < pb->data) //数据域比大小,将最小的连接到pc链表中
		{
			pc->next = pa; 
			pc = pa;
			pa = pa->next;
		}
		else
		{
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
	//结束之后出现了pa或者pb其中有一个已经为空了,进行接下来操作
	
	pc->next = pa ? pa : pb; //三目运算符 意思就是如果为真将pa后面的所有结点介入pc后面,否则把pb后面的结点街道pc后面
	free(*Lb); //释放链表Lb
	(*La) = (*Lb) = NULL; //最后将两个用过的链表置空
	
}

//多项式
void InitPolynomial(Polynomial* p, int length) //初始化
{
	(*p) = (Polynomial)malloc(sizeof(PolyNode)); //初始化头结点
	(*p)->next = NULL;

	printf("Please input the cofficient and exponent:"); //输入系数和指数
	for(int i=0; i<length; i++)
	{
		Polynomial pNew = (Polynomial)malloc(sizeof(PolyNode)); //先初始化一个新结点
		scanf(" %d", &(pNew->coeffcient)); //接收输入系数
		scanf(" %d", &(pNew->exponent)); //接收输入指数
		Polynomial q = (*p)->next; //q为指向比pNew->exponent大的结点
		Polynomial pre = (*p); //pre只想q的直接前驱结点

		while(q && q->exponent < pNew->exponent)
		{ //第一次的for循环不会执行
		  //直到找到一个结点的exponent大于pNew->exponent,如果没有找到q = NULL
			pre = q;
			q = q->next;
		}
        //当q->exponent > pNew->exponent,执行下列代码
		pNew->next = q;
		pre->next = pNew;
	}
}

void Traverse_P(Polynomial p) //遍历
{
	Polynomial s = p->next; //定义一个指针p始终首先指向首结点
	
	printf("%fX^%d",s->coeffcient,s->exponent);	//先输出第一项(不用前置符号)
	s=s->next;			//temp指针指向下一项
    while (s != NULL)		//循环输出后续项
    {
        if (s->coeffcient > 0)		//若为正系数
			printf(" +%fX^%d",s->coeffcient,s->exponent);
        else if (s->coeffcient < 0)	//若为负系数
			printf("%fX^%d",s->coeffcient,s->exponent);
        s = s->next;
    }
}


void AddPloynomial(Polynomial pa, Polynomial pb) //函数式相加
{
	Polynomial p1 = pa->next; //p1指向首结点
	Polynomial p2 = pb->next;
	Polynomial temp; //保留要删除的结点
	int sum = 0; //存放p1和p2的系数和
	while(p1 && p2) //p1和p2均未达到表尾 三种情况
	{	
		if(p1->exponent == p2->exponent) //第一种情况 指数相等,系数相加
		{	
			sum = (p1->coeffcient + p2->coeffcient);
			if( sum ) //系数相加和不为零
			{
				p1->coeffcient = sum;
				pa->next = p1;
				pa = pa->next;
				p1 = p1->next;
				temp = p2;
				p2 = p2->next;
				free(temp);

			}
			else
			{
				temp = p1;
				p1 = p1->next;
				free(temp);
				temp = p2;
				p2 = p2->next;
				free(temp);
				
			}
		}
		else if(p1->exponent > p2->exponent) //第二种情况
		{
			pa->next = p2;
			pa = pa->next;
			p2 = p2->next;
		}
		else //最后一种情况
		{
			pa->next = p1;
			pa = pa->next;
			p1 = p1->next;
		}
	}
	if(p1)
		pa->next = p1;
	else
		pa->next = p2;
	
}


//多项式的加法计算
void AddPloynomial_1(Polynomial pa, Polynomial pb)//pa,pb分别为多项式一和多项式二的头指针
{
	Polynomial p = pa->next;		//p为遍历指针,此时指向多项式一的第一项
    Polynomial q = pb->next;		//q为遍历指针,此时指向多项式二的第一项
    Polynomial pre=pa;			//pre此刻指向多项式一的头指针,后续作为中间载体
    Polynomial u;				//u指针做临时指针,用于释放节点
    while (p!=NULL && q!=NULL)//若指针指向的内容都不为空
    {
        if (p->exponent > q->exponent)//若多项式一中的项系数大于对应多项式二中的项
        {
            pre = p ; 
			p = p->next;
        }
        else if(p->exponent == q->exponent)//若两项系数相等则合并同类项
        {
            int x = p->coeffcient + q->coeffcient;//x为合并后的系数
            if (x != 0)				//若合并后系数不为零
            {
                p->coeffcient = x;		//将合并后的系数赋给多项式一中对应的项
                pre=p;				//pre指向p结点
            }
            else					//若合并后系数为零
            {
                pre->next = p->next;//指向下一个结点
                free(p);			//释放p销毁结点
            }
            p = pre->next;
            u = q;
            q = q->next;
            free(u);
        }
        else				//若多项式一中的项系数小于对应多项式二中的项
		{
            u = q->next;
            q->next = p;
            pre->next = q;
            pre = q ;
            q = u;
        }
    }
    if (q)
    {
        pre->next = q;
    }
    free(pb);
}

void Print(Polynomial head) /*输出多项式*/
{
	head=head->next;
	while(head)
	{
		if(head->exponent)
			printf("(%dx^%d)",head->coeffcient,head->exponent);
		else
			printf("(%d)",head->coeffcient);
		if(head->next)
			printf("+");
		else
			break;
		head=head->next;
	}
	printf("\n");
}
# ifndef _DEFINE_H
# define _DEFINE_H

# define TRUE 1
# define FALSE 0
# define OK 1
# define ERROR 0
# define INFEASIBLE -1
# define OVERFLOW -2
typedef int Status;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值