使用自定義的簡單順序表實現一元多項式的構造,計算值和加減
阿新 • • 發佈:2020-07-21
1、實現簡單的順序表
2、使用順序表實現一元多項式的構造
一、實現簡單的順序表
#include "ElemType.h" #include "stdlib.h" #ifndef DATASTRUCTURE_SQLIST_H #define DATASTRUCTURE_SQLIST_H #endif //DATASTRUCTURE_SQLIST_H /** * 線性表的順序表示和實現(陣列) */ //操作成功 #define OK 1 //操作錯誤 #define ERROR 0 //操作異常 #define OVERFLOW -2 //定義元素型別,int可使用基本資料型別和使用者自定義資料型別替換,根據使用場景選擇typedef int Status ; /** * 順序表的儲存結構 */ //predefine(預定義) constant(常量) maxn(n的最大值) #define MAXN 100 typedef struct { ElemType *elems; //儲存空間的基地址 int length; //線性表當前長度 }SqList;//sequence(序列) List(列表) /** * 順序表(順序結構的線性表)的基本操作的實現 */ /** * 構造一個空的順序表L * 演算法描述:開闢空間,設定順序表長度為零,返回操作結果 * @param L 指向順序表的指標L * @return 操作結果狀態碼*/ Status initList(SqList *L){ //為順序表分配一個大小為MAXN的陣列空間 if(L==NULL) //printf a flag printf("this is a flag\n"); ; L->elems = (ElemType *)malloc(sizeof(ElemType)*MAXN); //儲存分配失敗,返回OVERFLOW,表示操作異常狀態 if(!L->elems) return OVERFLOW; //設定順序表長度為零 L->length = 0; //構造順序表成功,返回OKreturn OK; } /** * 取順序表L中第i個元素elem * 演算法描述:判斷i是否大於等於1且小於順序表長度,返回ElemType陣列下標為i-1的元素 * @param L 指向順序表的指標L * @param i 要獲取的元素在順序表中的位置 * @return 操作結果狀態碼 */ Status getElem(SqList *L, int i, ElemType *e){ //如果i值不合法,返回ERROR表示操作錯誤 if(i < 1 || i > L->length){ return ERROR; } //將陣列的第i個元素的賦值給e指向的記憶體 *e = L->elems[i-1]; //操作成功,返回OK return OK; } /** * 查詢元素在順序表中的位置 * 演算法描述:查詢順序表中和元素e相同的元素出現的位置,若沒有和e匹配的元素,返回0 * @param L 指向順序表的指標L * @param e 要查詢的元素 * @return 元素在順序表中的位置 */ int indexOf(SqList *L, ElemType e){ for (int i = 0; i < L->length; ++i) { //查詢成功, 下標為i的元素是順序表的第i+1個元素,返回i+1 if(e == L->elems[i]){ return i+1; } } //查詢失敗,返回0 return 0; } /** * 在順序表L的第i個位置插入元素e,順序表長度加1 * 演算法描述:若i小於1或者i大於順序表L的當前長度加1,返回ERROR, * 若儲存空間已滿,返回ERROR,首先需要將順序表位置為n~i的元素依次後移,再在順序表位置i上插入元素e,順序表的長度加1 * @param L 指向順序表的指標L * @param i 插入位置i * @param e 要插入的元素e * @return 返回操作結果狀態碼 */ Status insertElem(SqList *L, int i, ElemType e){ //若i小於1或者i大於線性表L的當前長度,返回ERROR if(i < 1 || i > L->length + 1) return ERROR; //如果儲存空間已滿,返回ERROR if(L->length == MAXN) return ERROR; //將線性表位置為n~i的元素依次後移 for (int j = L->length; j >= i; --j) { L->elems[j] = L->elems[j-1]; } //在順序表位置i上插入元素e L->elems[i-1] = e; //線順序表的長度加1 ++L->length; return OK; } /** * 刪除順序表L上位置為i的元素,順序表長度減1 * 演算法描述:若i小於1或者i大於順序表L的當前長度,返回ERROR, * 將順序表位置為i+1~n的元素依次前移,順序表的長度減1 * @param L 指向順序表的指標L * @param i 刪除位置i * @return 返回操作結果狀態碼 */ Status deleteElem(SqList *L, int i){ //若i小於1或者i大於順序表L的當前長度,返回ERROR if(i < 1 || i > L->length) return ERROR; //將線性表位置為i+1~n的元素依次前移 for (int j = i; j < L->length; ++j) { L->elems[j-1] = L->elems[j]; } //順序表的長度減1 --L->length; return OK; } Status clearList(SqList *L){ L->length = 0; }
二、使用順序表實現一元多項式的構造
一元多項式的ADT(Abstract Data Type)
ADT UnaryPoly{ 資料物件:D = {p0, p1, ... , pn| n(-N, p(-R} 資料關係:R = {<p0, p1, ..., pn>| p0是一元n次多項式P(之後簡稱P)的0次項的係數, p1是P的1次項的係數, ..., pn是P的n次項的係數} 基本操作: create(&P, p0, p1, ..., pn) 操作結構:構造一元n次多項式P calculate(&ans, P, x) 初始條件:P是一元n次多項式, x是實數 操作結構:確定P的元,計算一元n次多項式的值並返回 add(&P, P1, P2) 初始條件:P1, P2是一元多項式 操作結果:返回P1, P2的和 sub(&P, P1, P2) 初始條件:P1, P2是一元多項式 操作結果:返回P1, P2的差 }ADT UnaryPoly;
使用順序表的基本操作實現一元多項式的基本操作
#include<stdio.h> #include "SqList.h" #include<math.h> #include<algorithm> using namespace std; /** * 使用順序表實現一元多項式 */ /** * 實現一元多項式的基本操作 */ /** * 根據長度為n的係數陣列p構造一元n次多項式L, 若n < 0 , 輸入不合法, 返回ERROR * @param L 指向一元被建立的一元多項式的指標 * @param p 一元多項式L0到n次項的係數陣列的基址 * @param n 一元多項式L的最高次數 * @return 操作結果狀態碼 */ Status create(SqList *L, double *p, int n) { //若n < 0 , 輸入不合法, 返回ERROR if (n < 0)return ERROR; //初始化順序表,得到一張空表,如果初始化失敗,返回OVERFLOW if (initList(L) != OK) { return OVERFLOW; } //依次插入係數陣列p下標為0, 1, ..., n-1的元素到順序表的第1, 2, ..., n個位置,如果插入失敗,返回ERROR for (int i = 0; i <= n; ++i) { if (insertElem(L, i + 1, p[i]) != OK) { return ERROR; } } //構造一元多項式成功,返回OK return OK; } /** * 對於確定的元為x的一元多項式L, 計算其值v * 若L不存在(未初始化), 返回ERROR * @param v 一元多項式的值 * @param L 指向一元多項式的指標 * @param x 給定的一元多項式的未知數的值 * @return 操作結果狀態碼 */ Status calculate(double *v, SqList *L, double x) { //L不存在(未初始化), 返回ERROR if (L == NULL) return ERROR; //設定一元多項式的初始值為0,然後依次累加每項的值並返回 *v = 0; double *p = new double ; for (int i = 0; i < L->length; ++i) { //若取值失敗,返回ERROR if (getElem(L, i + 1, p) != OK) return ERROR; *v += pow(x, i) * (*p); } //計算成功返回OK return OK; } /** * 求和 * 兩個一元多項式L1,L2求和,返回和L * @param L1 指向被加一元多項式L1的指標 * @param L2 指向加一元多項式L2的指標 * @param L 指向一元多項式L1與L2之和的指標 * @return 操作結果狀態碼 */ Status add(SqList *L1, SqList *L2,SqList *L) { //L1, L2未初始化, 返回ERROR if (L1 == NULL || L2 == NULL) return ERROR; //初始化失敗,返回OVERFLOW if(initList(L)!=OK) return OVERFLOW; //初始化成功,進行多項式求和 int len = max(L1->length,L2->length); for (int i = 0; i < len; ++i) { //設定和多項式L的次數為i的項的係數為零 double p = 0; double *p1 =new double ; //若L1包含次數為i的項,即L1的第i+1個元素,使多項式L的次數為i的係數加上L1對應次數項的係數 if(i<L1->length){ //獲取元素失敗,返回ERROR if(getElem(L1,i+1,p1)!=OK) return ERROR; p += *p1; } //若L2包含次數為i的項,即L2的第i+1個元素,使多項式L的次數為i的係數加上L2對應次數項的係數 if(i<L2->length){ //獲取元素失敗,返回ERROR if(getElem(L2,i+1,p1)!=OK) return ERROR; p += *p1; } //和多項式新增係數為p,次數為i的項作為第i+1一個元素 if(insertElem(L,i+1,p)!=OK)return ERROR; } return OK; } /** * 求差 * 兩個一元多項式L1,L2求差,返回和L * @param L1 指向被減一元多項式L1的指標 * @param L2 指向減一元多項式L2的指標 * @param L 指向一元多項式L1與L2之差的指標 * @return 操作結果狀態碼 */ Status sub(SqList *L1, SqList *L2,SqList *L) { //L1, L2未初始化, 返回ERROR if (L1 == NULL || L2 == NULL) return ERROR; //初始化失敗,返回OVERFLOW if(initList(L)!=OK) return OVERFLOW; //初始化成功,進行多項式求和 int len = max(L1->length,L2->length); for (int i = 0; i < len; ++i) { //設定和多項式L的次數為i的項的係數為零 double p = 0; double *p1 = new double ; //若L1包含次數為i的項,即L1的第i+1個元素,使多項式L的次數為i的係數加上L1對應次數項的係數 if(i<L1->length){ //獲取元素失敗,返回ERROR if(getElem(L1,i+1,p1)!=OK) return ERROR; p += *p1; } //若L2包含次數為i的項,即L2的第i+1個元素,使多項式L的次數為i的係數減去L2對應次數項的係數 if(i<L2->length){ //獲取元素失敗,返回ERROR if(getElem(L2,i+1,p1)!=OK) return ERROR; p -= *p1; } //和多項式新增係數為p,次數為i的項作為第i+1一個元素 if(insertElem(L,i+1,p)!=OK)return ERROR; } return OK; }
測試一元多項式的基本操作的功能
int main() { double p1[] = {1,2,1}; double p2[] = {1,0,4,3}; SqList *L1,*L2; L1 = new SqList ; L2 = new SqList ; if(create(L1,p1,2)!=OK)return 0; if(create(L2,p2,3)!=OK)return 0; int x = 3; double *v1,*v2,*v; v1 = new double ; v2 = new double ; v = new double ; if(calculate(v1,L1,x)!=OK)return 0; if(calculate(v2,L2,x)!=OK)return 0; //printf a flag printf("%lf\n",*v1); printf("%lf\n", *v2); SqList *L = new SqList ; if(add(L1,L2,L)!=OK)return 0; if(calculate(v,L,x)!=OK)return 0; printf("%lf\n", *v); if(clearList(L)!=OK)return 0; if(sub(L1,L2,L)!=OK)return 0; if(calculate(v,L,x)!=OK)return 0; printf("%lf\n", *v); return 0; }
測試結果