实验题一:线性表的基本运算
一、问题描述
实现顺序表和单链表的基本运算,能够正确演示线性表的查找、插入、删除运算。熟练掌握顺序表的各种基本操作。学会使用线性表解决应用问题的方法。实现单链表的定义和基本操作。实现顺序表的逆置。
二、概要设计
main函数代码如图所示:
三、详细设计
线性表的基本运算程序中包括三个文件,分别为: linearlist.h,seqlist.h,LinearListMain.cpp。其中顺序表类seqlist.h中,私有段封装了两个私有数据成员maxLenght和elements,同时继承了LinearList类中的n,分别存储表中元素最多个数,元素和元素的实际个数。其中核心算法代码如下:
1.实现顺序表的逆置
2.删除表中等于x的元素
3.算法分析
线性表的基本运算程序的主要算法的算法时间复杂度和空间复杂度为O(n)。
四、测试结果
实验题二:一元多项式的相加和相乘
一、问题描述
设计带表头结点的单链表表示多项式实现输入并建立多项式,输出多项式和多项式运算。重载*运算符。以线性表来描述一元多项式,存储结构采用单链表,每个结点存储的多项式中某一项的系数和指数,建立单链表的元素按指数递减有序排列。
二、概要设计
main函数代码如图:
三、详细设计
多项式的加法和乘法算术运算程序中包括了三个文件,分别为Polynominal.h,Term.h,main.cpp。其中项结点类Team中定义了三个私有数据域,即系数coef、指数exp和指向下一个项结点的指针域link并且polynominal 被声明成了项结点类Team的友元。
其中,核心程序代码如下:
四、算法分析
多项式的加法和乘法算术运算程序的主要算法的时间复杂程度和和空间复杂程度为O(n)。
五、测试结果
六、实验小结
数据结构有很强的逻辑性,因此我认为如果在上机之前先把逻辑搞清楚很重要,不管是对算法的设计还是对程序的调试都有很大帮助。经过一次上机实践,我认为实践课很重要,上理论课只是纸上谈兵,只是被动地接受,而实践课上能将学过的知识利用起来,同时还有一些东西只能是自己上机实践才能慢慢探索出的。
设计过程中遇到了很多问题,多是一些细节上的东西。比如,有些变量重复定义了,有些变量又没有定义,在调用函数就直接复制过来,没有修改参数,等等。让我也意识到细节决定成败,以后会更多的注意细节方面。大部分的时间都用在了编程上,主要是因为C语言掌握的问题,C语言基础不好特别是对于C语言中链表的一些定义和基本操作不够熟练,导致在编程过程中还要不断的拿着c 语言的教材查找,所以今后还要对C语言多练习,多动手,多思考。
在与同学的交流中,我不断找出并修改了自己的错误,也不断加深了我对这门课的理解和兴趣,相信在以后的学习中我会做的越来越好。
附录:
线性表的基本运算:
#include
template
class LinearList
{
public:
virtual bool IsEmpty() const=0;
virtual int Length() const=0;
virtual bool Find(int i,T& X) const=0;
virtual int Search(T x) const=0;
virtual bool Insert(int i,T x)=0;
virtual bool Delete(int i)=0;
virtual bool Update(int i,T x)=0;
virtual void Output(ostream& out) const=0; virtual void Reverse()=0;
virtual bool DeleteX(const T&x)=0; protected:
int n;
};
template
class Seqlist:public LinearList
{
public:
Seqlist(int mSize);
~Seqlist() {delete [] elements;}
bool IsEmpty() const;
int Length() const;
bool Find(int i,T& X) const;
int Search(T x) const;
bool Insert(int i,T x);
bool Delete(int i);
bool Update(int i,T x);
void Output(ostream& out) const;
void Reverse();
bool DeleteX(const T&x);
private:
int maxLength; //顺序表的最大长度
T *elements; //动态一位数组的指针
};
template
Seqlist
{
maxLength=mSize;
elements=new T[maxLength]; //动态分配顺序表的储存空间n=0;
}
template
bool Seqlist
{
return n==0;
}
template
int Seqlist
{
return n;
}
template
bool Seqlist
{
if(i<0||i>n-1)
{
cout<<"Out of Bounds"< } x=elements[i]; return true; } template int Seqlist { for(int j=0;j if(elements[j]==x) return j; return -1; } template bool Seqlist { if(i<-1||i>n-1) { cout<<"Out of Bounds"< } if(n==maxLength) { cout<<"OverFlow"< } for(int j=n-1;j>i;j--) elements[j+1]=elements[j]; elements[i+1]=x; n++; return true; } template bool Seqlist { if(!n){ cout<<"UnderFlow"< } if(i<0||i>n-1){ cout<<"Out of Bounds"< } for(int j=i+1;j n--;return true; } template bool Seqlist { if(i<0||i>n-1) { cout<<"Out of Bounds"< } elements[i]=x; return true; } template void Seqlist for(int i=0;i out< } template { T t; for(int i=0;i { t=elements[i]; elements[i]=elements[n-i-1]; elements[n-i-1]=t; } } template bool Seqlist { if(Search(x)==-1) return false; for(int i=0;i { if(elements[i]==x) { Delete(i); i--; } } return true; } template void Union(Seqlist { T x; for(int i=0;i { LB.Find(i,x); if(LA.Search(x)==-1) LA.Insert(LA.Length()-1,x); } } const int SIZE=20; void main() //主函数用于测试对线性表的各种操作 { Seqlist //Seqlist for(int i=0;i<10;i++) LA.Insert(i-1,i); LA.Output(cout); LA.Insert(3,3); LA.Insert(3,3); LA.Insert(3,3); LA.Output(cout); LA.DeleteX(3); LA.Output(cout); LA.Reverse(); //for(i=5;i<10;i++) LB.Insert(i-6,i); //LB.Insert(-1,0); //LB.Insert(3,2); //LB.Insert(LB.Length()-1,4); //Union(LA,LB); LA.Output(cout); } 多项式的算术运算: #include class Term { public: Term(int c,int e); Term(int c,int e,Term *nxt); Term *InsertAfter(int c, int e); private: int coef; int exp; Term *link; friend ostream & operator<<(ostream &, const Term &); friend class Polynominal; }; Term::Term(int c,int e):coef(c),exp(e) { link=0; } Term::Term(int c,int e,Term *nxt):coef(c),exp(e) { link=nxt; } Term *Term::InsertAfter(int c, int e) { link=new Term(c, e, link); return link; } ostream & operator<<(ostream & out, const Term & val) { if(val.coef==0) return out; out< switch(val.exp){ case 0:break; case 1:out<<"x";break; default:out<<"x^"< } return out; } class Polynominal { public: Polynominal(); ~Polynominal(); void AddTerms(istream & in); void Output(ostream & out)const; void PolyAdd(Polynominal & r); //多项式相加 void PolyMul(Polynominal & r); //多项式相乘 private: Term *theList; friend ostream & operator<<(ostream &, const Polynominal &); friend istream & operator>>(istream &, Polynominal &); friend Polynominal & operator+(Polynominal &,Polynominal &); friend Polynominal & operator*(Polynominal &,Polynominal &); }; Polynominal::Polynominal() { theList=new Term(0,-1); theList->link=theList; } Polynominal::~Polynominal() { Term *p=theList->link; while(p!=theList){ theList->link=p->link; delete p; p=theList->link; } delete theList; } void Polynominal::AddTerms(istream & in) { Term *q=theList; int c,e; for(;;) { cout<<"请输入多项式系数和指数:\n"< cin>>c>>e; if (e<0) break; q=q->InsertAfter(c,e); } } void Polynominal::Output(ostream& out) const { int first=1; Term *p=theList->link; cout<<"结果为:\n"< for ( ; p!=theList&&p!=NULL;p=p->link) { if (!first && (p->coef>0)) out<<"+"; first=0; out<<*p; } cout<<"\n"< } void Polynominal::PolyAdd(Polynominal& r) { Term* q,*q1=theList,*p; //q1指向表头结点 p=r.theList->link; //p指向第一个要处理的结点 q=q1->link; //q1是q的前驱,p和q就指向两个当前进行比较的项 while (p->exp>=0) //对r的单循环链表遍历,直到全部结点处理完{ while (p->exp { q1=q; q=q->link; } if(p->exp==q->exp) //当指数相等时,系数相加 { q->coef=q->coef+p->coef; if(q->coef==0) //若相加后系数为0,则删除q { q1->link=q->link; delete(q); q=q1->link; //重置q指针 } else { q1=q; q=q->link; } //若相加后系数不为0,则移动q1和q } else //p->exp->exp的情况 q1=q1->InsertAfter(p->coef,p->exp); //以p的系数和指数生产新结点,插入q1后 p=p->link; } } void Polynominal::PolyMul(Polynominal& r) { Term *q,*q1=theList,*p; //q1指向表头结点 q=q1->link; //q1是q的前驱,p和q就指向两个当前进行比较的项while(q->exp>=0) //对r的单循环链表遍历,直到全部结点处理完 { p=r.theList->link; //p指向第一个要处理的结点 while (p->exp>=0) { q1=q1->InsertAfter(q->coef*p->coef,q->exp+p->exp); p=p->link; } q1->link=q->link; delete(q); q=q1->link; } } ostream& operator <<(ostream &out,const Polynominal &x) { x.Output(out); return out; } istream& operator >>(istream& in, Polynominal &x) { x.AddTerms(in); return in; } Polynominal & operator+(Polynominal &a, Polynominal &b) { a.PolyAdd(b); return a; } Polynominal & operator*(Polynominal &a, Polynominal &b) { a.PolyMul(b); return a; } void main() { Polynominal m,n,k; cin>>m; cout<