1.基础知识回顾:单链表结点结构包括数据域和一个指向另一结点的指针域,如果你要访问单链表中任意的一个元素时,需要将指针从头到尾的往下搜索,所以此时单链表的平均时间复杂度为O(n/2), 而要得到某一结点的后继结点,则只需要o(1),时间复杂度,你要得到前一个结点,不好意思,此时将非常麻烦,因为在单链表中,没前存储头一结点的指针,所以此时你需要从头到尾的进行遍历一次,此时的时间复杂度将是O(n),呵呵,比较麻烦吧,没关系,在数据结构中,提出了一种双向循环链表用于解决这个问题,这时的结点中会存储包含前一结点的指针.以后在给出双向循环链表的源代码.
下面是单链表的一些基本相关操作源代码,代码比较简单的.就请各位自己理解下吧,有问题可以告诉我!
///
// Book name : C++ structure and algorithm
// FileName : SList.cpp
// Version : 1.0
// Author : Yangfei
// Date : 2010-04-05 9:21:38
// Comment : 单链表类,应用:一元多项式
//
///
///
// 结点结构:| data | *next|
///
#include <iostream>
#include <exception>
#include <assert.h>
using namespace std;
template <class T>
class CNode
{
public:
T data;
CNode<T>* next;
public:
CNode():data(T()),next(NULL){}
CNode(T _data):data(_data),next(NULL){}
CNode(T _data,CNode<T>* e):data(_data),next(e){}
//friend class SList<T>;
};
template <class T>
class SList
{
private:
CNode<T>* first;
int m_nCount;
public:
SList():first(NULL),m_nCount(0){}
bool IsEmpty() const
{
if(first==NULL)
return true;
return false;
}
//单链表的相关操作说明
int AddHead(const T data);
int AddTail(const T data);
int InsertPosbefore(const int pos,const T data);
int InsertPosafter(const int pos,const T data);
void DeleteHead();
void DeleteTail();
void DeleteAll();
T& GetTail();
T GetTail() const;
T& GetHead();
T GetHead() const;
T& GetAtpos(const int pos);
T GetAtpos(const int pos) const;
int GetCount() const;
void SetAtpos(const int pos,const T data);
int Find(const T data) const;
};
//template <class T>
//int SList<T>::m_nCount=0;
template <class T>
int SList<T>::AddHead(const T data)
{
CNode<T>* newNode=new CNode<T>();
if(!newNode)
{
cout<<"it's failed!"<<endl;
return 0;
}
else
{
newNode->data=data;
newNode->next=first;
first=newNode;
m_nCount++;
return 1;
}
}
template <class T>
int SList<T>::AddTail(const T data)
{
CNode<T>* newNode=new CNode<T>();
if(!newNode)
{
cout<<"it's failed!"<<endl;
return 0;
}
newNode->data=data;
if(first==NULL)
{
first=newNode;
newNode->next=NULL;
m_nCount++;
return 1;
}
else
{
CNode<T>* tempNode=first;
while(tempNode)
{
if(tempNode->next==NULL)
break;
tempNode=tempNode->next;
}
newNode->next=tempNode->next;
tempNode->next=newNode;
m_nCount++;
return 1;
}
}
template <class T>
int SList<T>::InsertPosbefore(const int pos, const T data)
{
if(pos<0||pos>m_nCount)
{
cout<<"pos is error!"<<endl;
return 0;
}
CNode<T>* tempNode=first;
CNode<T>* newNode=new CNode<T>();
if(!newNode)
{
cout<<"it's failed!"<<endl;
return 0;
}
for(int i=1;i<pos-1;i++)
tempNode=tempNode->next;
newNode->data=data;
newNode->next=tempNode->next;
tempNode->next=newNode;
m_nCount++;
return 1;
}
template <class T>
int SList<T>::InsertPosafter(const int pos,const T data)
{
if(pos<0||pos>m_nCount)
{
cout<<"pos is error!"<<endl;
return 0;
}
CNode<T>* tempNode=first;
CNode<T>* newNode=new CNode<T>();
if(!newNode)
{
cout<<"it's failed!"<<endl;
return 0;
}
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
newNode->data=data;
newNode->next=tempNode->next;
tempNode->next=newNode;
m_nCount++;
return 1;
}
template <class T>
void SList<T>::DeleteAll()
{
CNode<T>* tempNode;
while(first)
{
tempNode=first;
first=first->next;
delete tempNode;
}
m_nCount=0;
}
template <class T>
void SList<T>::DeleteHead()
{
if(IsEmpty())
cout<<"SList is empty!"<<endl;
else
{
CNode<T>* tempNode=first;
first=first->next;
delete tempNode;
m_nCount--;
}
}
template <class T>
void SList<T>::DeleteTail()
{
if(IsEmpty())
cout<<"SList is empty!"<<endl;
else if(m_nCount==1)
{
delete first;
first=NULL;
}
else
{
CNode<T>* tempNode=first;
CNode<T>* tempNode1=tempNode;
while(tempNode)
{
if(tempNode->next==NULL)
break;
tempNode1=tempNode;
tempNode=tempNode->next;
}
delete tempNode;
tempNode1->next=NULL;
}
}
template <class T>
T& SList<T>::GetHead()
{
assert(!IsEmpty());
return first->data;
}
template <class T>
T SList<T>::GetHead() const
{
if(!IsEmpty())
{
return first->data;
}
return 0;
}
template <class T>
T SList<T>::GetTail() const
{
if(!IsEmpty())
{
CNode<T>* tempNode=first;
while(tempNode)
{
if(tempNode->next==NULL)
break;
tempNode=tempNode->next;
}
return tempNode->data;
}
return false;
}
template <class T>
T& SList<T>::GetTail()
{
if(!IsEmpty())
{
CNode<T>* tempNode=first;
while(tempNode)
{
if(tempNode->next==NULL)
break;
tempNode=tempNode->next;
}
return tempNode->data;
}
return false;
}
template <class T>
T& SList<T>::GetAtpos(const int pos)
{
assert(pos>0||pos<=m_nCount);
CNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
return tempNode->data;
}
template <class T>
T SList<T>::GetAtpos(const int pos) const
{
if(pos<=0||pos>m_nCount)
return false;
CNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
return tempNode->data;
}
template <class T>
int SList<T>::GetCount() const
{
return m_nCount;
}
template <class T>
void SList<T>::SetAtpos(const int pos,const T data)
{
if(pos<0||pos>m_nCount)
cout<<pos<<"is error!"<<endl;
else
{
CNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
tempNode->data=data;
}
}
template <class T>
int SList<T>::Find(const T data) const
{
if(!IsEmpty())
{
CNode<T>* tempNode=first;
int pos=0;
while(tempNode)
{
pos++;
if(tempNode->data=data)
return pos;
tempNode=tempNode->next;
}
return 0;
}
return 0;
}
//单链表应用:一元多项式的应用
///多项式每一项的定义
//#define Max(x,y) (x)>(y)?(x):(y); //取大者
typedef struct flagPolyNomial
{
SList<float> coef; //系数
int expn; //指数
}* PolyNomial;
//多项式加法
void AddPolyNomial(PolyNomial& sumPoly,PolyNomial& poly1,PolyNomial& poly2)
{
int maxPower;
maxPower=((poly1->expn)>(poly2->expn))?(poly1->expn):(poly2->expn);
sumPoly->expn=maxPower;
for(int i=0;i<=maxPower;i++)
{
sumPoly->coef.AddTail(poly1->coef.GetAtpos(i+1)+poly2->coef.GetAtpos(i+1));
}
}
//多项式乘法算法,利用多项式加法实现
void MultiPolyNomial(PolyNomial multiPoly,PolyNomial poly1,PolyNomial poly2)
{
multiPoly->expn=poly1->expn+poly2->expn;
float temp;
float temp1;
float temp2;
for(int k=0;k<=multiPoly->expn;k++)
multiPoly->coef.AddHead(0);
for(int i=0;i<=poly1->expn;i++) //i,j标记幂
{
temp=poly1->coef.GetAtpos(i+1);
for(int j=0;j<=poly2->expn;j++)
{
temp1=multiPoly->coef.GetAtpos(i+j+1);
temp2=poly2->coef.GetAtpos(j+1);
temp1+=temp*temp2;
multiPoly->coef.SetAtpos(i+j+1,temp1);
}
/*foat temp=poly1->coef.GetAtpos(i+1);
for(int j=0;j<=poly2->expn;j++)
{
PolyNomial tempPoly=new flagPolyNomial;
tempPoly->coef.AddHead(temp*poly2->coef.GetAtpos(j+1));
}*/
}
}
void printResultPoly(PolyNomial ResultPoly)
{
for(int i=ResultPoly->expn;i>=0;i--)
{ if(i==0)
{ //if(sumPoly->coef.GetAtpos(i+1)==0)
// break; //当最后的常数为0时,如何去年这个0及前置+号?
//else
cout<<ResultPoly->coef.GetAtpos(i+1)<<endl;
}
else if(ResultPoly->coef.GetAtpos(i+1)==0)
continue;
else
cout<<ResultPoly->coef.GetAtpos(i+1)<<"x^"<<i<<"+";
}
}
//主函数调用
int main()
{
//单链表测试
SList<int> slist;
slist.AddTail(12);
slist.SetAtpos(1,4);
cout<<slist.GetHead()<<endl;
cout<<slist.GetCount()<<endl;*/
//多项式测试poly1=5x^3+7x+6;poly2=x^4+5x^2+9x+35
PolyNomial sumPoly,poly1,poly2;
sumPoly=new flagPolyNomial;
poly1=new flagPolyNomial;
poly2=new flagPolyNomial;
poly1->expn=3;
poly1->coef.AddHead(0);
poly1->coef.AddHead(5);
poly1->coef.AddHead(0);
poly1->coef.AddHead(7);
poly1->coef.AddHead(6);
poly2->expn=4;
poly2->coef.AddHead(1);
poly2->coef.AddHead(0);
poly2->coef.AddHead(5);
poly2->coef.AddHead(9);
poly2->coef.AddHead(35);
cout<<poly1->coef.GetCount()<<" "<<poly2->coef.GetCount()<<endl;
//一元多项式加法测试
AddPolyNomial(sumPoly,poly1,poly2);
printResultPoly(sumPoly);
PolyNomial multiPoly=new flagPolyNomial;
//一元多项式乘法测试
MultiPolyNomial(multiPoly,poly1,poly2);
printResultPoly(multiPoly);
return 0;
}
2.上面的单链表中实现了两个基本的应用,一元多项式的加法与乘法操作.效率问题还将就着,我存储结构用了单链表来存储多项式的系数.