1. 程式人生 > >一元多項式加法、乘法連結串列實現

一元多項式加法、乘法連結串列實現

       一元多項式的實現包含連結串列的定義,讀入,插入,輸出等基本操作,是學習連結串列基本操作的好例項。這裡對一元多項式的加法、乘法分開分析和實現,其中多項式是按指數遞減儲存的。兩個程式碼都經過除錯是正確的,由於使用的是C++編譯的,輸入函式使用scanf()函式有安全問題,所以使用的是scanf_s()函式,但scanf_s()函式在C中除錯會編譯錯誤,需要改回scanf()函式。

  1. 一元多項式的加法

      對一個多項式通過連結串列實現加法,需要建立連結串列結構體,讀入連結串列,連結串列插入(指數比較係數相加),結果輸出等幾個步驟。這裡輸出時若多項式相加為零多項式,輸出為“0 0”。

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


//定義結構體
struct PolyNode
{
	int coef;	//係數
	int expon;	//指數
	struct PolyNode *link;	//指向下一個節點指標
};
typedef struct PolyNode *Polynomial;	

//多項式讀入函式
Polynomial PolyRead();

//比較函式
int Compare(int , int );

//新增結點函式
void Attach(int , int , Polynomial* );

//多項式求和函式
Polynomial PolyAdd(Polynomial , Polynomial );

//連結串列輸出
void PrintPoly(Polynomial P);

int main()
{
	Polynomial P1, P2, R_Add, R_Mult;
	P1 = PolyRead();
	P2 = PolyRead();

	R_Add = PolyAdd(P1, P2);
	PrintPoly( R_Add);

	system("pause");

	return 0;
}

//多項式讀入函式,直接讀入
Polynomial PolyRead()	
{
	int N;
	scanf_s("%d", &N);
	Polynomial Head , Rear, Tmp; //定義的應該是指標,需要分配空間才能使用

	Rear = (Polynomial) malloc(Len);	//分配空間
	Rear->link = NULL;	//表頭空結點
	Head = Rear;

	for(int i=0; i< N; i++)	//建立連結串列
	{
		Tmp = (Polynomial) malloc( Len);	//申請新結點
		Tmp->link = NULL;
		scanf_s("%d", &Tmp->coef );
		scanf_s("%d", &Tmp->expon );
		Rear->link = Tmp;	//新結點插入尾部
		Rear = Tmp;

	}
	Tmp = Head;
	Head = Head->link;
	free(Tmp);	//刪除臨時空的頭結點

	return Head;
}

//比較函式
int Compare(int e1, int e2)
{
	//比較兩項指數e1和e2,根據大、小、等三種情況分別返回1,-1,0
	if(e1 > e2) return 1;
	else if(e1 < e2) return -1;
	else return 0;

}


//新增結點函式
void Attach(int coef, int expon, Polynomial *PtrRear)
{
	//本函式需要改變當前結果表示式的尾指標的值
	//函式傳遞進來的是尾項指標的地址
	Polynomial P;

	//申請新結點並賦值
	P=(Polynomial) malloc(sizeof(struct PolyNode));
	P->coef = coef;
	P->expon = expon;
	P->link = NULL;

	//將P指向新結點插入到當前結果表示式尾項後面
	(*PtrRear) ->link = P;
	*PtrRear = P;	//修改PtrRear值
}


//多項式求和函式
Polynomial PolyAdd(Polynomial P1, Polynomial P2)
{
	Polynomial front, rear, temp;
	int sum;
	//為方便表頭插入,先產生一個臨時空結點作為結果多項式連結串列頭
	rear = (Polynomial) malloc(sizeof(struct PolyNode));
	front = rear;	//由front記錄結果多項式的表頭
	while(P1 && P2)
	{
		switch( Compare(P1->expon, P2->expon))
		{
		case 1:
			Attach(P1->coef, P1->expon, &rear);
			P1 = P1->link;
			break;
		case -1:
			Attach(P2->coef, P2->expon, &rear);
			P2 = P2->link;
			break;
		case 0:
			sum = P1->coef + P2->coef;
			if(sum) Attach(sum, P1->expon, &rear);
			P1 = P1->link;
			P2 = P2->link;
			break;
		}
	}
	//將為處理完的另一項多項式的所有結點依次複製到結果多項式中
	for(; P1; P1=P1->link) Attach(P1->coef, P1->expon, &rear);
	for(; P2; P2=P2->link) Attach(P2->coef, P2->expon, &rear);
	rear->link = NULL;
	temp = front;
	front = front->link;	//front指向結果多項式第一非零項

	free(temp);	//刪除臨時空的頭結點
	return front;

}

//連結串列輸出
void PrintPoly(Polynomial P)
{
	//輸出多項式
	int flag = 0;
	
	if(P ==NULL) printf("0 0");
	while(P)
	{
		if(!flag) flag = 1;	//頭結點為空不輸出
		else 
			printf(" ");
		printf("%d %d", P->coef, P->expon);

		P = P->link ;
		
	}
	printf("\n");
	
}

2.一元多項式的乘法

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

//定義結構體
struct PolyNode
{
	int coef;	//係數
	int expon;	//指數
	struct PolyNode *link;	//指向下一個節點指標
};
typedef struct PolyNode *Polynomial;	

//多項式讀入函式
Polynomial PolyRead();

//新增結點函式
void Attach(int , int , Polynomial* );

//多項式求乘積函式
Polynomial PolyMultiply(Polynomial , Polynomial);

//連結串列輸出
void PrintPoly(Polynomial P);

int main()
{
	Polynomial P1, P2, R_Add, R_Mult;
	P1 = PolyRead();
	P2 = PolyRead();

	R_Mult = PolyMultiply(P1, P2);	
	PrintPoly(R_Mult);

	system("pause");    //VS中除錯結果輸出暫停

	return 0;
}

//多項式讀入函式
Polynomial PolyRead()	
{
	Polynomial P,Rear,t;
	int c, e, N;
	scanf_s("%d", &N);	//讀入結點個數
	P =(Polynomial) malloc(sizeof(struct PolyNode));
    P->link = NULL;
	Rear = P;	//指向同一空頭結點

	while(N--)
	{
		scanf_s("%d %d", &c, &e);	
		Attach(c, e, &Rear);
	}
	t= P; P= P->link; free(t);	//刪除臨時空的頭結點

	return P;
}

//新增結點函式
void Attach(int coef, int expon, Polynomial *PtrRear)
{
	//本函式需要改變當前結果表示式的尾指標的值
	//函式傳遞進來的是尾項指標的地址
	Polynomial P;

	//申請新結點並賦值
	P=(Polynomial) malloc(sizeof(struct PolyNode));
	P->coef = coef;
	P->expon = expon;
	P->link = NULL;

	//將P指向新結點插入到當前結果表示式尾項後面
	(*PtrRear) ->link = P;
	*PtrRear = P;	//修改PtrRear值
}

//多項式求乘積函式
Polynomial PolyMultiply(Polynomial P1, Polynomial P2)
{
	Polynomial P, Rear, t1, t2, t;
	int c, e;

	if(!P1 || !P2) return NULL;
	t1= P1; t2 = P2;
	P=(Polynomial) malloc(sizeof(struct PolyNode));		//P為輸出的乘積指標
	P->link = NULL;
	Rear = P;

	while(t2)	//先將t1第一項和t2相乘並加入Rear
		{	
			//t1,t2係數相乘,指數相加	
			Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
			t2= t2->link;
	}
	t1= t1->link;

	while(t1)
	{
		t2 = P2;	Rear = P;	//指標從頭迴圈
		while(t2)
		{
			c = t1->coef * t2->coef;	//t1,t2係數相乘,指數相加
			e = t1->expon + t2->expon;

			while(Rear->link && Rear->link->expon >e)
				Rear = Rear->link;
			if(Rear->link && Rear->link->expon == e)
			{
				Rear->link->coef += c; 
				if(Rear->link->coef == 0)
				{
					t = Rear->link;
					Rear->link = t->link;
					free(t);	//刪除指數為0結點
				}
			}
			else
			{
				t =(Polynomial) malloc(sizeof(struct PolyNode));
				t->coef =c;
				t->expon = e;
				t->link = Rear->link;
				Rear->link = t;	//插入t
				Rear = Rear->link;	//t2還在迴圈,需要繼續往後移動

			}

			t2= t2->link;
		}
		t1= t1->link;
	}
	t = P; 
	P= P->link;
	free(t);  
	return P;
}


//連結串列輸出
void PrintPoly(Polynomial P)
{
	//輸出多項式
	int flag = 0;
	
	if(P ==NULL) printf("0 0");
	while(P)
	{
		if(!flag) flag = 1;	//頭結點為空不輸出
		else 
			printf(" ");
		printf("%d %d", P->coef, P->expon);

		P = P->link ;	
	}
	printf("\n");
	
}