1. 程式人生 > >一元多項式的表示及相加(抽象資料型別Polynomial的實現)

一元多項式的表示及相加(抽象資料型別Polynomial的實現)

// c2-6.h 抽象資料型別Polynomial的實現(見圖2.45)
typedef struct // 項的表示,多項式的項作為LinkList的資料元素
{
float coef; // 係數
int expn; // 指數
}term,ElemType; // 兩個型別名:term用於本ADT,ElemType為LinkList的資料物件名

圖246 是根據c2-5.h 和c2-6.h 定義的多項式7.3+22X7 的儲存結構。


// bo2-7.cpp 多項式(儲存結構由c2-6.h定義)的基本操作及演算法2.22,2.23等(8個)
#include"c2-5.h"
#include"bo2-6.cpp"
typedef LinkList polynomial;
#define DestroyPolyn DestroyList // 與bo2-6.cpp中的函式同義不同名
#define PolynLength ListLength // 與bo2-6.cpp中的函式同義不同名
void OrderInsertMerge(LinkList &L,ElemType e,int(* compare)(term,term))
{ // 按有序判定函式compare()的約定,將值為e的結點插入或合併到升序連結串列L的適當位置
	Position q,s;
	if(LocateElem(L,e,q,compare)) // L中存在該指數項
	{
		q->data.coef+=e.coef; // 改變當前結點係數的值
		if(!q->data.coef) // 係數為0
		{ // 刪除多項式L中當前結點
			s=PriorPos(L,q); // s為當前結點的前驅
			if(!s) // q無前驅
				s=L.head;
			DelFirst(L,s,q);
			FreeNode(q);
		}
	}
	else // 生成該指數項並插入連結串列
	{
		MakeNode(s,e); // 生成結點
		InsFirst(L,q,s);
	}
}
int cmp(term a,term b) // CreatPolyn()的實參
{ // 依a的指數值<、=或>b的指數值,分別返回-1、0或+1
	if(a.expn==b.expn)
		return 0;
	else
		return (a.expn-b.expn)/abs(a.expn-b.expn);
}
void CreatPolyn(polynomial &P,int m) // 演算法2.22
{ // 輸入m項的係數和指數,建立表示一元多項式的有序連結串列P
	Position q,s;
	term e;
	int i;
	InitList(P);
	printf("請依次輸入%d個係數,指數:\n",m);
	for(i=1;i<=m;++i)
	{ // 依次輸入m個非零項(可按任意順序)
		scanf("%f,%d",&e.coef,&e.expn);
		if(!LocateElem(P,e,q,cmp)) // 當前連結串列中不存在該指數項,cmp是實參
		{
			MakeNode(s,e); // 生成結點並插入連結串列
			InsFirst(P,q,s);
		}
	}
}
void PrintPolyn(polynomial P)
{ // 列印輸出一元多項式P
	Link q;
	q=P.head->next; // q指向第1個結點
	printf(" 係數指數\n");
	while(q)
	{
		printf("%f %d\n",q->data.coef,q->data.expn);
		q=q->next;
	}
}
void AddPolyn(polynomial &Pa,polynomial &Pb) // 演算法2.23
{ // 多項式加法:Pa=Pa+Pb,並銷燬一元多項式Pb
	Position ha,hb,qa,qb;
	term a,b;
	ha=GetHead(Pa);
	hb=GetHead(Pb); // ha和hb分別指向Pa和Pb的頭結點
	qa=NextPos(ha);
	qb=NextPos(hb); // qa和qb分別指向Pa和Pb中當前結點(現為第1個結點)
	while(!ListEmpty(Pa)&&!ListEmpty(Pb)&&qa)
	{ // Pa和Pb均非空且ha沒指向尾結點(qa!=0)
		a=GetCurElem(qa);
		b=GetCurElem(qb); // a和b為兩表中當前比較元素
		switch(cmp(a,b))
		{
		case -1:ha=qa; // 多項式Pa中當前結點的指數值小
			qa=NextPos(ha); // ha和qa均向後移1個結點
			break;
		case 0: qa->data.coef+=qb->data.coef; // 兩者的指數值相等,修改Pa當前結點的係數值
			if(qa->data.coef==0) // 刪除多項式Pa中當前結點
			{
				DelFirst(Pa,ha,qa);
				FreeNode(qa);
			}
			else
				ha=qa;
			DelFirst(Pb,hb,qb);
			FreeNode(qb);
			qb=NextPos(hb);
			qa=NextPos(ha);
			break;
		case 1: DelFirst(Pb,hb,qb); // 多項式Pb中當前結點的指數值小
			InsFirst(Pa,ha,qb);
			ha=ha->next;
			qb=NextPos(hb);
		}
	}
	if(!ListEmpty(Pb))
	{
		Pb.tail=hb;
		Append(Pa,qb); // 連結Pb中剩餘結點
	}
	DestroyPolyn(Pb); // 銷燬Pb
}
void AddPolyn1(polynomial &Pa,polynomial &Pb)
{ // 另一種多項式加法的演算法:Pa=Pa+Pb,並銷燬一元多項式Pb
	Position qb;
	term b;
	qb=GetHead(Pb); // qb指向Pb的頭結點
	qb=qb->next; // qb指向Pb的第1個結點
	while(qb)
	{
		b=GetCurElem(qb);
		OrderInsertMerge(Pa,b,cmp);
		qb=qb->next;
	}
	DestroyPolyn(Pb); // 銷燬Pb
}
void Opposite(polynomial Pa)
{ // 一元多項式Pa係數取反
	Position p;
	p=Pa.head;
	while(p->next)
	{
		p=p->next;
		p->data.coef*=-1;
	}
}
void SubtractPolyn(polynomial &Pa,polynomial &Pb)
{ // 多項式減法:Pa=Pa-Pb,並銷燬一元多項式Pb
	Opposite(Pb);
	AddPolyn(Pa,Pb);
}
void MultiplyPolyn(polynomial &Pa,polynomial &Pb)
{ // 多項式乘法:Pa=Pa×Pb,並銷燬一元多項式Pb
	polynomial Pc;
	Position qa,qb;
	term a,b,c;
	InitList(Pc);
	qa=GetHead(Pa);
	qa=qa->next;
	while(qa)
	{
		a=GetCurElem(qa);
		qb=GetHead(Pb);
		qb=qb->next;
		while(qb)
		{
			b=GetCurElem(qb);
			c.coef=a.coef*b.coef;
			c.expn=a.expn+b.expn;
			OrderInsertMerge(Pc,c,cmp);
			qb=qb->next;
		}
		qa=qa->next;
	}
	DestroyPolyn(Pb); // 銷燬Pb
	ClearList(Pa); // 將Pa重置為空表
	Pa.head=Pc.head;
	Pa.tail=Pc.tail;
	Pa.len=Pc.len;
}

// main2-7.cpp 檢驗bo2-7.cpp的主程式
#include"c1.h"
#include"c2-6.h"
#include"bo2-7.cpp"
void main()
{
	polynomial p,q;
	int m;
	printf("請輸入第1個一元多項式的非零項的個數:");
	scanf("%d",&m);
	CreatPolyn(p,m);
	printf("請輸入第2個一元多項式的非零項的個數:");
	scanf("%d",&m);
	CreatPolyn(q,m);
	AddPolyn(p,q);
	printf("2個一元多項式相加的結果:\n");
	PrintPolyn(p);
	printf("請輸入第3個一元多項式的非零項的個數:");
	scanf("%d",&m);
	CreatPolyn(q,m);
	AddPolyn1(p,q);
	printf("2個一元多項式相加的結果(另一種方法):\n");
		PrintPolyn(p);
	printf("請輸入第4個一元多項式的非零項的個數:");
	scanf("%d",&m);
	CreatPolyn(q,m);
	SubtractPolyn(p,q);
	printf("2個一元多項式相減的結果:\n");
	PrintPolyn(p);
	printf("請輸入第5個一元多項式的非零項的個數:");
	scanf("%d",&m);
	CreatPolyn(q,m);
	MultiplyPolyn(p,q);
	printf("2個一元多項式相乘的結果:\n");
	PrintPolyn(p);
	DestroyPolyn(p);
}

執行結果如下:

相關推薦

一元多項式表示相加(抽象資料型別Polynomial實現)

// c2-6.h 抽象資料型別Polynomial的實現(見圖2.45) typedef struct // 項的表示,多項式的項作為LinkList的資料元素 { float coef; // 係數 int expn; // 指數 }term,ElemType; //

連結串列做的一元多項式表示相加

 #include<stdio.h> #include<stdlib.h> #include<malloc.h> struct node {  int num;  int f;  struct node *next; }; typed

Polynomial 一元多項式表示相加 (線性連結串列實現 嚴蔚敏版)

1、貼程式碼: #include <iostream> #include <cstdio> using namespace std; struct Node { double coef; int expn; Node *next; }; v

資料結構—— 一元多項式表示相加(C語言實現

程式碼比較簡單,沒有完全按照嚴蔚敏版《資料結構(C語言版)》上39頁到43頁上的要求,只是實現了簡單功能,且此程式碼輸入多項式時只能按升冪的順序輸入(因為沒有寫多項式排序的函式) 個人感覺此程式碼短小精悍,且易理解,看懂了的話可以嘗試完全按照書上的要求自己寫程式

資料結構】演算法2.22-2.23 一元多項式表示相加

#include<stdio.h> #include<string.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERRO

資料結構 一元多項式表示相加

/* typedef struct {     float coef; //係數     int expn;   //指數 }term,ElemType; //定義結構體  typedef LinkList polynomial;  //用帶頭結點的有序連結串列表示多項式

資料結構——一元多項式表示相加(C語言)

//一元多項式的表示及相加 #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #defi

【圖(上)】什麼是圖,抽象資料型別,怎麼表示一個圖

什麼是圖 表示“多對多”的關係 包含 一組頂點:通常用V (Vertex) 表示頂點集合 一組邊:通常用E (Edge) 表示邊的集合 邊是頂點對:

線性表的抽象資料型別求兩陣列的並集

1.operation     InitList(*L):初始化操作,建立一個空的線性表L.      ListEmpty(L):判斷線性表是否為空表,若為空,則返回true,否則返回false。     

資料結構--抽象資料型別三元組Triplet的表示實現

抽象資料型別三元組Triplet的表示和實現。 資料型別是一個值的集合和定義在這個值集上的一組操作的總稱。按“值”的不同特性,高階程式語言中的資料型別可分為兩類:一類是非結構的原子型別,原子型別的值是不可分解的;另一類是結構型別,結構型別的值是由若干成分按某種結構組成的,因此是可以分解的

資料結構與演算法》之抽象資料型別(ADT)

抽象資料型別(abstract data type,ADT)是帶有一組操作的一些物件的集合。抽象資料型別是數學的抽象,只不過這種資料型別帶有自己的操作。比如表、集合、圖以及與它們各自的操作一起形成的這些物件都可以看做抽象資料型別,就像整數、實數、布林數等都是資料型別一樣。整數、實數、布林數都有各自相

繪製直線,基本的資料型別

#include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <iostream

抽象資料型別ADT

根據程式設計的問題匹配合適的資料型別。資料項連線構成了連結串列,定義了一個結構代表單獨的項。設計了一些方法把一系列結構構成一個連結串列。本質上,我們使用C語言的功能設計了一種符合程式要求的新的資料型別。但是上述的做法不繫統。我們要使用更系統的方法定義資料型別。   型別指兩種資訊:屬性和操作。

【Redis】Redis資料庫五種資料型別圖解

目錄 Redis資料庫: 是什麼? 優勢? 資料型別(五種): 1.字串: 2.hash型別: 3.list型別: 4.set型別: 5.zset型別: Redis資料庫: 是什麼? 一類新出現的,非關係型的,不支援SQL語法的,不支援事物,|

如何理解資料結構中的抽象資料型別

##抽象資料型別的標準格式 ADT 抽象資料型別名 { Data: 資料元素之間邏輯關係的定義; Operation: 操作1; 操作2; ... } ##什麼是抽象資料型別? 抽象資料型別(Abstract Data Type,ADT)是指一個數學模型以及定義在這個模型上的一

C++ primer 讀書筆記 第七章 01 定義抽象資料型別

定義成員函式 成員函式的宣告必須在類的內部,它的定義既可以在類的內部也可以在類的外部。 struct Sales_data { std::string isbn() const { return bookNo; } double arv_price() co

抽象資料型別線性表的定義與實現

最近剛剛上完資料結構的第一章,好久沒有寫線性表了,正好藉著老師的作業溫習一下,主程式實現的就是簡單的list有序合併。不多比比,直接上程式碼 第一部分 de.hpp檔案 // // main.cpp // test // // Created by 蔡

Redis簡單介紹5種資料型別的使用

Redis簡介 關於關係型資料庫和nosql(not only sql)資料庫(泛指非關係型資料庫) 關係型資料庫是基於關係表的資料庫,最終會將資料持久化到磁碟上,而nosql(不僅僅是資料庫)資料庫是基於特殊的結構,並將資料儲存到記憶體的資料庫。從效能上而言,nosql資料庫要

【 C 】經典抽象資料型別(ADT)之記憶體分配

C中的一些抽象資料型別(ADT)如連結串列、堆疊、佇列和樹等,連結串列已經在前幾篇博文有所討論,見: 後面的博文會相繼討論堆疊、佇列和樹的一些基本的相關知識! 下面記錄一個最基本的問題,記憶體分配問題: 所有的 ADT 都必須明確一個問題,如何獲取記憶體

抽象資料型別(ADT)

int printlist(struct LIST L) { int i; printf("name stuno age score/n");  for(i=0;i<L.length;i++)  printf("%s %s/t%d/t%d/n", L.stu[i].name, L.stu[i].stun