数据结构-一元多项式操作

本项目是老师发的框架,自己简单填写了加、减、乘、求导、积分的部分代码。

目标效果:

加法:

减法和乘法与加法类似,就不贴结果图了。

求导:

积分:


下面贴几个主要页面:

1.Mutualplat.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("\n选择你想进行的运算方法:\n[A](add),[S](substract),[M](multiply),[D](Derivative),[C](Calculus)---");

}

//输入运算命令
Status GetCommand(char& way)
{
	printf("\n运算方法为:");
	readM(way);
	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


2.LinkList.h页面:

/*
   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);

		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;
		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("+  ");
    }
    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 )
{
    if((int)co==co)
        printf("%d X^%d ",(int)co,ex);
    else
        printf("%.2f X^%d ",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


3.Polynomial.h页面:
/*
   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)     //查找这一位置
			{
				s=s->next;
				k++;
			}
			s->coef *= co;    //系数项相减

		}
		else       //不存在相同的指数,将Pb中的该项插入Pa
			ListInsert(Pa, 1, co, ex);
	}
	DestroyList(Pb);	//销毁Pb

}


//完成多项式的求导函数,即:Pa = Pa'
void Derivative(polynomial &P)
{
    UnionList(P);   //合并一元多项式中具有

    LinkList p;
    p=P;
	for (int i=1; i<=ListLength(P)+1; i++)
	{
		float co;
		int ex;
		p=p->next;
		co=p->coef;
		ex=p->expn;
        if(ex==0){
            ListDelete(P,i,co,ex);
            continue;
        }
		p->coef=co*ex;
		p->expn=ex-1;
	}
}

//完成多项式的积分函数, Pa = ∫Pa' dx
void Calculus (polynomial &P)
{
    UnionList(P);   //合并一元多项式中具有

    LinkList p;
    p=P;
	for (int i=1; i<=ListLength(P); i++)
	{
		float co;
		int ex;
		p=p->next;
		co=p->coef;
		ex=p->expn;

		p->coef=co/(ex+1);
		p->expn=ex+1;
	}
}



#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif

#endif  // POLYNOMIAL_H_INCLUDED


源码链接:点击打开链接






版权声明:本文为hester_hester原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。