本人弱鸡,在学数据结构,学到链表这一章,思索实践搜集资料了好几天才对单链表有了一些理解。现在整理一些代码与感悟,希望看到这篇文章也同样在学链表的童鞋能有所感悟,少走些弯路。
结点类(我比较喜欢用结构体,这样可避免友元的问题,也比较清晰) :
template <class T>
struct chainNode {
T data;
chainNode<T> *link;
chainNode(chainNode <T> *pre = NULL) { link = pre; }
chainNode(const T& item, chainNode<T> *pre = NULL) {
data = item;
link = pre;
}
};
注意上述结构体中的两个构造函数,first = new chainNode<T>; 调用的便是第一个构造函数,这个first指针指向的便是不带值的头结点(头结点也可以带值,但不算是我们期待的链表中的值)。
first = new chainNode<T>(x),这调用的是第二个构造函数,这时候链表便不带头结点。
List类:
template <class T>
class List {
public:
List() { first = new chainNode<T>; } //带头结点
List(const T& x) { first = new chainNode<T>(x); } //这是不带头结点的
List(List<T> &L); //复制构造函数
~List() { makeEmpty(); }
chainNode<T>* locate(int i); //返回链表中第i个元素的地址
void makeEmpty(); //将链表清空
bool IsEmpty() const { return first->link == NULL ? true : false; }
void inputFront(T endTag);
void inputRear(T endTag);
int length() const; //计算带有头结点的链表的长度
int search(T &x); //返回链表第一个x是第几个值
void find(int k, T& x); //找到链表中第k个元素,并把它的值赋给x
void output(ostream& out);
bool remove(int k, T& x);
bool insert(int k, T& x);
void reverse(