没想到我的第一个数据结构程序竟然写了3个礼拜多,无聊的电工实习和更无聊的期中考试耽误我不少时间,编写过程中的困难也大大超出了我的预计。以下是我写的代码,其中肯定有很多不妥的矛盾的地方,希望可以得到指正。
//LinkList.h
#ifndef LINKLIST_H
#define LINKLIST_H

template <class T>
struct Node

...{
T coef;
T exp;
Node<T> *next;
};

template <class T>
class LinkList

...{
public:
LinkList();
LinkList(T a[][2],int n);
~LinkList();
void Insert(T a,T b,int loc);
void Delete(int loc);
void Print();
LinkList<T> operator+(LinkList<T> &l2);
LinkList<T> operator*(LinkList<T> &l2);
private:
Node<T> *first;
};

#endif
//LinkList.cpp
#include "LinkList.h"

template <class T>
LinkList<T>::LinkList()

...{
first=new Node<T>;
first->next=NULL;
}

template <class T>
LinkList<T>::LinkList(T a[][2],int n)

...{
first=new Node<T>;
first->next=NULL;
for(int i=1;i<=n;i++)
Insert(a[i-1][0],a[i-1][1],i);
}

template <class T>
LinkList<T>::~LinkList()

...{
//
}

template <class T>
void LinkList<T>::Insert(T a,T b,int loc)

...{
Node<T> *temp;
temp=new Node<T>;
temp->coef=a;
temp->exp=b;

Node<T> *p=first;
for(int i=1;i<loc;i++)
p=p->next;
temp->next=p->next;
p->next=temp;
}

template <class T>
void LinkList<T>::Delete(int loc)

...{
Node<T> *p=first;
for(int i=1;i<loc;i++)
p=p->next;
Node<T> *q=p->next;
p->next=p->next->next;
delete q;
}

template <class T>
void LinkList<T>::Print()

...{
Node<T> *p=first->next;
while(p)

...{
cout<<p->coef<<"x^"<<p->exp<<" ";
p=p->next;
}
cout<<endl;
}

template <class T>
LinkList<T> LinkList<T>::operator+(LinkList<T> &l2)

...{
LinkList<T> sum;
Node<T> *p=first->next;
Node<T> *q=l2.first->next;
Node<T> *r=sum.first;
int loc=1;
while(p && q)

...{
if(p->exp<q->exp)

...{
sum.Insert(p->coef,p->exp,loc);
loc++;
p=p->next;
}
else if(p->exp>q->exp)

...{
sum.Insert(q->coef,q->exp,loc);
loc++;
q=q->next;
}
else

...{
if(p->coef+q->coef==0)

...{
p=p->next;
q=q->next;
}
else

...{
sum.Insert(p->coef+q->coef,p->exp,loc);
p=p->next;
q=q->next;
loc++;
}
}
}
while(p)

...{
sum.Insert(p->coef,p->exp,loc);
p=p->next;
loc++;
}
while(q)

...{
sum.Insert(q->coef,q->exp,loc);
q=q->next;
loc++;
}
return sum;
}

template<class T>
LinkList<T> LinkList<T>::operator*(LinkList<T> &l2)

...{
LinkList<T> sum;
Node<T> *p=first->next;
Node<T> *q;
int loc=1;
while(p)

...{
LinkList<T> *temp=new LinkList<T>;
q=l2.first->next;
while(q)

...{
temp->Insert(p->coef*q->coef,p->exp+q->exp,loc);
loc++;
q=q->next;
}
sum=sum+(*temp);
delete temp;
loc=1;
p=p->next;
}
return sum;
}
上述代码中各项的实现方法我就不做具体分析了,很多书上都有而且肯定比我分析得好,有看不懂的地方也可以问我。这里要讲的是一些容易出错的地方,相信很多人在写链表时也和我一样遇到过许多莫名的错误,甚至让人觉得是电脑的问题。但是电脑毕竟是很按部就班的机器,绝大多数错误都源于代码中的bug。这些错误的代码的共同点是让人觉得理所当然,当然也就很难发现,发现了才意识到是多么愚蠢的错误。我曾一度这样定义插入函数:
template <class T>
void LinkList<T>::Insert(T a,T b,int loc)

...{
Node<T> *temp;
temp->coef=a;
temp->exp=b;

Node<T> *p=first;
for(int i=1;i<loc;i++)
p=p->next;
temp->next=p->next;
p->next=temp;
}
这段代码看起来貌似没有什么错误,其实在声明*temp时并没有为它分配空间,导致当程序执行到 temp->coef=a 时,没有一个可以存放a的值的空间。注意了,如果已有另一个Node<T>型的指针p,那么 Node<T> *temp; temp=p; 自然是合法的,因为系统会把temp指向p所指向的数据空间。将这两种情况放在一起就会发现很容易混淆,而像这样的问题编译器是不会通知你的。由于在构造函数中调用了插入函数,使得我根本无法定义一个链表,最后通过断点步进才找到了错误的地方,在此要顺便感谢一下Samson的帮助。其实在写程序的过程中像这样的低级错误在所难免,所以不应忽视一下细节上的问题。
关于这个程序的分析只能暂时写到这里,程序中还有一些让人困惑的地方目前我还不能做出明确的解释(比如链表的析构函数为什么为空),只能以后再做补充。最后要说明一下在这个程序中并没有使用迭代器类,关于迭代器会在我以后的文章中做初步的讨论。