主要代碼
/****************************************************
@title: 數據結構實驗
@name:<試驗> 一元多項式簡單計算器
@object:
[實驗目的]
單鏈表的存儲結構及其基本操作的實現
[實驗提示]
1. 在linklist.h中實現單鏈表的基本操作
2.在Polynomial.h中實現了一元多項式的基本操作
3.在Polynomial.h中編寫代碼,進行測試
4.在MutualPlat.h中編寫一交互式的運行平臺
@include:
ds.h [*]
單鏈表的實現
@author: wangheng
@date: 3 / 4 / 2017
***************************************************/
#define Number 2.0
#include <stdio.h>
#include <stdlib.h>
#include "MutualPlat.h"
int main()
{
printf("是否進行運算(Y/N): ");
char command;
polynomial P1;
polynomial P2;
read(command);
while(command == 'Y')
{
run(); //運行程序
printf("是否進行運算(Y/N): ");
readM(command);
}
return 0;
}
/*
Name: LinkList.h
Author: WangHeng
Data: 3 / 4 / 2017 ;
Description: 1)建立一個交互式的平臺,實現創建和運行運算的功能
2)調用一元多項式的頭文件Polynomial.h,進行調用
*/
#ifndef MUTUALPLAT_H_INCLUDED
#define MUTUALPLAT_H_INCLUDED
//////////////////////////////////////////
//應用的頭文件
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ds.h"
#include "Polynomial.h"
///////////////////////////////////////////
//輸入函數:調用一元多項式的CreatPolyn()函數進行輸入
void input (polynomial& P)
{
//1)輸入第一個一元多項式各項
printf("\n輸入一個一元多項式的各項係數和指數[當輸入的係數和指數爲:(0 0) 時,輸入結束]\n");
CreatPolyn(P);
//打印輸出一元多項式P1
PrintPolyn(P);
//輸出一元多項式的項數
printf("一元多項式的項數: %d\n",PolynLength(P));
}
//運算方法清單
void CaculateMenu()
{
printf("選擇你想進行的運算方法:[A](add),[S](substract),[M](multiply),\n[D](Derivative),[C](Calculus)---");
}
//輸入運算命令
Status GetCommand(char& way)
{
printf("\n運算方法爲:");
readM(way);
printf("\n");
return OK;
}
//交互式運行平臺
void run( )
{
char way;
polynomial P1;
polynomial P2;
//3)選擇運算方法
CaculateMenu();
GetCommand(way);
switch(way)
{
case 'A' : //兩個一元多項式的和
case 'a':
input(P1); //輸入一元多項式的各項
input(P2);
AddPolyn(P1,P2);
//打印輸出和
printf("打印輸出和:\n");
PrintPolyn(P1);
break;
case 'S' : //兩個一元多項式的差
case 's':
input(P1); //輸入一元多項式的各項
input(P2);
SubtractPolyn(P1,P2);
//打印輸出差
printf("打印輸出差:\n");
PrintPolyn(P1);
break;
case 'M' : //兩個一元多項式的積
case 'm':
input(P1); //輸入一元多項式的各項
input(P2);
MultiplyPolyn(P1,P2);
//打印輸出積
printf("打印輸出積:\n");
PrintPolyn(P1);
break;
case 'D':
case 'd':
input(P1); //輸入一元多項式的各項
Derivative(P1);
//打印輸出導數
printf("打印輸出 P1 導數: \n");
PrintPolyn(P1);
break;
case 'C':
case 'c':
input(P1); //輸入一元多項式的各項
Calculus (P1);
//打印輸出積分
printf("打印輸出 P1 積分: \n");
PrintPolyn(P1);
break;
default:
printf("輸入的運算方法錯誤:");
}
//銷燬一元多項式
DestroyPolyn(P1);
}
#endif // MUTUALPLAT_H_INCLUDED
/*
Name: Polynomial.h
Author: WangHeng
Data: 3 / 4 / 2017 ;
Description: 1)調用LinkList.h頭文件,用實現鏈表的各種功能
來創建一元多項式的各種算法實現;
2)調用ds.h來進行基本的輸入輸出等操作
3)頭文件Polynomial.h主要完成一元多項式的各種操作
*/
#ifndef POLYNOMIAL_H_INCLUDED
#define POLYNOMIAL_H_INCLUDED
#ifndef ElemType
#define ElemType int //數據類型默認爲int
#define ELEMTYPE_TAG
#endif
#include "ds.h"
#include "LinkList.h"
typedef LinkList polynomial;
/*************************************************************************
* 基本操作的函數原型說明
*************************************************************************/
//輸入m項的係數和指數,建立表示一元多項式的有序鏈表P
void CreatPolyn(polynomial &P, int m);
//銷燬一元多項式P
void DestroyPolyn(polynomial &P);
//打印輸出一元多項式P
void PrintPolyn(polynomial P);
//返回一元多項式P中的項數
int PolynLength(polynomial P);
//完成多項式相加運算,即:Pa = Pa + Pb,並銷燬一元多項式Pb
void AddPolyn(polynomial &Pa,polynomial &Pb);
//完成多項式相減運算,即:Pa = Pa - Pb,並銷燬一元多項式Pb
void SubtractPolyn(polynomial &Pa,polynomial &Pb);
//完成多項式相乘運算,即:Pa = Pa * Pb,並銷燬一元多項式Pb
void MultiplyPolyn(polynomial &Pa,polynomial &Pb);
//完成多項式的求導函數,即:Pa = Pa'
void Derivative(polynomial &P);
//完成多項式的積分函數, Pa = ∫Pa' dx
void Calculus (polynomial &P);
/*********************************************************************
* 基本操作的算法描述和實現
*********************************************************************/
//創建一元多項式P,當輸入的指數和係數都爲0時,輸入結束。
// 一元多項式就被創建 。
void CreatPolyn(polynomial &P)
{
InitList(P);
printf(" \n輸入係數和指數:\n");
read(P->coef,P->expn); //輸入係數和指數
//-------------------TODO------------------//
while(P->coef!=0||P->expn!=0){
ListInsert(P, 1, P->coef, P->expn);
printf(" \n輸入係數和指數:\n");
read(P->coef,P->expn);
}
//------------初始化表達式,不斷輸入係數和指數,直到讀到0,0爲止----------//
}
//銷燬一元多項式P
void DestroyPolyn(polynomial &P)
{
DestroyList(P); //調用LinkList.h頭文件中的銷燬函數
}
//打印輸出一元多項式P
void PrintPolyn(polynomial P)
{
printf("打印一員多項式的各系數和指數\n ");
UnionList(P); //用來合併在一元多項式計算結果中具有相同指數的項
PrintLinkList(P);
}
//返回一元多項式P中的項數
int PolynLength(polynomial P)
{
return ListLength(P); //合併後的一元多項式的項數
}
//完成多項式相加運算,即:Pa = Pa + Pb,並銷燬一元多項式Pb
void AddPolyn(polynomial &Pa,polynomial &Pb)
{
UnionList(Pa); //合併一元多項式中具有
UnionList(Pb); //相同指數的項
for (int i=1; i<=ListLength(Pb); i++)
{
float co;
int ex;
GetElem(Pb, i, co, ex);
if(LocateElem(Pa, ex) > 0) //判斷Pa中是否具有Pb中相同指數的項,
{ //如果有,進行相加
int j = LocateElem(Pa, ex); //記錄Pa中相同項的位置
int k = 0;
polynomial s = Pa;
while(k < j) //查找這一位置
{
//-------------------TODO------------------//
s=s->next;
k++;
}
s->coef += co; //係數項相加
}
else //不存在相同的指數,將Pb中的該項插入Pa
ListInsert(Pa, 1, co, ex);
}
DestroyList(Pb); //銷燬Pb
}
//完成多項式相減運算,即:Pa = Pa - Pb,並銷燬一元多項式Pb
void SubtractPolyn(polynomial &Pa,polynomial &Pb)
{
UnionList(Pa); //合併一元多項式中具有
UnionList(Pb); //相同指數的項
for (int i=1; i<=ListLength(Pb); i++)
{
float co;
int ex;
GetElem(Pb, i, co, ex);
if(LocateElem(Pa, ex) > 0) //判斷Pa中是否具有Pb中相同指數的項,
{ //如果有,進行相加
int j = LocateElem(Pa, ex); //記錄Pa中相同項的位置
int k = 0;
polynomial s = Pa;
while(k < j) //查找這一位置
{
//-------------------TODO------------------//
s=s->next;
k++;
}
s->coef -= co;
}
else //不存在相同的指數,將Pb中的該項插入Pa
ListInsert(Pa, 1, co, ex);
}
DestroyList(Pb); //銷燬Pb
}
//完成多項式相乘運算,即:Pa = Pa * Pb,並銷燬一元多項式Pb
void MultiplyPolyn(polynomial &Pa,polynomial &Pb)
{
UnionList(Pa); //合併一元多項式中具有
UnionList(Pb); //相同指數的項
for (int i=1; i<=ListLength(Pb); i++)
{
float co;
int ex;
GetElem(Pb, i, co, ex);
if(LocateElem(Pa, ex) > 0) //判斷Pa中是否具有Pb中相同指數的項,
{ //如果有,進行相加
int j = LocateElem(Pa, ex); //記錄Pa中相同項的位置
int k = 0;
polynomial s = Pa;
while(k < j) //查找這一位置
{
//-------------------TODO------------------//
s=s->next;
k++;
}
s->coef *= co; //係數項相加
}
else //不存在相同的指數,將Pb中的該項插入Pa
ListInsert(Pa, 1, co, ex);
}
DestroyList(Pb); //銷燬Pb
}
//完成多項式的求導函數,即:Pa = Pa'
void Derivative(polynomial &P)
{
polynomial Pb=P->next;
float co;
int ex;
while(Pb)
{
co=(Pb->coef) * (Pb->expn);
ex=Pb->expn-1;
Pb->coef=co;
Pb->expn=ex;
Pb=Pb->next;
}
DestroyList(Pb); //銷燬Pb
}
//完成多項式的積分函數, Pa = ∫Pa' dx
void Calculus (polynomial &P)
{
polynomial Pb=P->next;
float co;
int ex;
while(Pb)
{
ex=Pb->expn+1;
co=Pb->coef/ex;
Pb->coef=co;
Pb->expn=ex;
Pb=Pb->next;
}
DestroyList(Pb);
}
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif
#endif // POLYNOMIAL_H_INCLUDED
/*
Name: LinkList.h
Author: WangHeng
Data: 3 / 4 / 2017 ;
Description: 引用老師的鏈表結構,在此基礎上進行修改,
使其適合一元多項式.
*/
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED
#include "ds.h"
#ifndef ElemType
#define ElemType int //數據類型默認爲int
#define ELEMTYPE_TAG
#endif
/****************************************************************
* 多項式的存儲結構定義
****************************************************************/
typedef struct LNode{
float coef; //係數
int expn; //指數
struct LNode *next;
} LNode,*LinkList;
/*************************************************************************
* 基本操作的函數原型說明
*************************************************************************/
//創建並初始化爲空表
Status InitList(LinkList &L);
//銷燬整個表(從此之後不再可用)
Status DestroyList(LinkList &L);
//將表L置空
Status ClearList(LinkList &L);
//判斷表L是否爲空表
bool ListEmpty(LinkList L);
//求表L的長度
int ListLength(LinkList L);
//取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR
Status GetElem(LinkList L, int i, float &co, int &ex);
template <typename T> bool equal(T a, T b)
{
return a==b;
}
//在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0
// compare(a,b) 爲比較函數,匹配時返回true,否則返回false
// 這裏默認使用equal進行比較
int LocateElem(LinkList L, int ex,
bool (*compare)(int ,int )=equal<int >);
//在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR
Status ListInsert(LinkList &L, int i, float co , int ex);
//刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR
Status ListDelete(LinkList &L, int i, float &co, int &ex);
//遍歷表L,對每個元素調用visit(x).
Status ListTraverse(LinkList L, Status (*visit)(float,int));
//合併一元多項式中相同的冪的項
void UnionList(LinkList &L);
/**********************************************************
* 單鏈表的基本操作的實現
***********************************************************/
//創建並初始化爲空表
Status InitList(LinkList &L)
{
L = (LNode*)malloc(sizeof(LNode));
if(!L) exit(DS_OVERFLOW);
L->next = NULL;
return OK;
}
//銷燬整個表(從此之後不再可用)
Status DestroyList(LinkList &L)
{
LinkList p ;
while (L )
{
p = L;
L = L->next;
free(p);
}
return OK;
}
//將表L置空
Status ClearList(LinkList &L)
{
LinkList p = L->next;
LinkList s ;
while (p )
{
s = p;
p = p->next;
free(s);
}
return OK;
}
//判斷表L是否爲空表
bool ListEmpty(LinkList L)
{
if(L->next == NULL)
return TRUE;
else
return FALSE;
}
//求表L的長度
int ListLength(LinkList L)
{
int j = 0;
LinkList p = L;
while (p ->next != NULL)
{
j++;
p = p->next;
}
return j;
}
//取表L中的第i個元素,並用返回. 操作成功返回OK,失敗時返回ERROR
Status GetElem(LinkList L, int i, float &co, int &ex)
{
if(i > ListLength(L) || i <= 0) return ERROR;
int j = 0;
LinkList p = L;
while(p&&j < i)
{
p = p->next;
j++;
}
if(p && j == i)
{
co = p->coef;
ex = p->expn;
return ex;
}
else
return ERROR;
//-------------------------------------
}
//在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0
// compare(a,b) 爲比較函數,匹配時返回true,否則返回false
int LocateElem(LinkList L, int ex, bool (*compare)(int , int))
{
// TODO (#1#): 在表中定位元素ex,用compare(a,b)匹配元素
LinkList p;
int j;
p = L->next; j = 0;
while(p) {
j++;
if( compare(p->expn,ex) ) return j;
p=p->next;
}
return 0;
//-------------------------------------
}
//在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR
Status ListInsert(LinkList &L, int i, float co, int ex)
{
// TODO (#1#): 在鏈表中插入元素
LinkList p = L;
int j = 0;
while(p && j < i - 1) //注意判斷條件
{
p = p->next ;
j++;
}
if(p && j == i-1)
{
LinkList s = (LNode *)malloc(sizeof(LNode)); //分配插入的結點
if(!s) exit(DS_OVERFLOW);
//-------------------TODO------------------//
s->coef=co;
s->expn=ex;
s->next = p->next;
p->next = s;
return OK;
}
else
return ERROR;
//-------------------------------------
}
//刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR
Status ListDelete(LinkList &L, int i, float &co, int &ex)
{
// TODO (#1#): 在鏈表中刪除元素
LinkList p = L;
int j = 0;
while(p && j < i-1 ) //注意判斷條件
{
p = p->next ;
j++;
}
if(p && j == i-1)
{
LinkList s = p->next;
p->next = s->next;
//-------------------TODO------------------//
co= s->coef;
ex= s->expn;
free(s);
return OK;
}
else
return ERROR;
//-------------------------------------
}
//遍歷表L,對每個元素調用visit(x).
Status ListTraverse(LinkList L, Status (*visit)(float,int))
{
LinkList p = L->next;
while ( p ) {
if ( visit(p->coef,p->expn)==ERROR ) return ERROR;
p = p->next;
printf("+\t");
}
return OK;
//--------------------------------------
}
//合併一元多項式中相同的冪的項
void UnionList(LinkList &L)
{
int ex1,ex2;
float co0,co1,co2;
LinkList p = L;
for(int i = 1; i < ListLength(L); i++)
{
GetElem(L, i, co1, ex1);
if(co1 == 0)
ListDelete(L, i, co1, ex1);
for (int j = i+1; j < ListLength(L)+1; j++)
{
GetElem(L, j, co2, ex2);
if(co2 == 0)
ListDelete(L, j, co2, ex2);
else if(ex2 == ex1)
{
co0 = co1 + co2; //解決在同一一元多項式中有相同係數的情況
ListDelete(L, j, co2, ex2);
ListDelete(L, i, co1, ex1);
ListInsert(L, i, co0, ex1);
}
}
}
}
/******************************************************
* 在程序設計時,所需的小型函數
*****************************************************/
// 打印數據元素的方法
Status print(float co,int ex )
{
printf("%.2f X^%2d \t",co,ex);
return OK;
}
//打印鏈表內容
void PrintLinkList(LinkList L)
{
ListTraverse(L,print); //遍歷鏈表並print()每個元素
printf("\n");
}
bool equal(int a, int b)
{
return a==b;
}
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif
#endif // LINKLIST_H_INCLUDED
演示效果: