链表的概念与结点类模板
顺序访问的线性群体——链表类
链表是一种动态数据结构,可以用来表示顺序访问的线性群体。
链表是由系列 结点 组成的,结点可以在运行时动态生成。
每一个结点包括 数据域 和指向链表中下一个结点的 指针 (即下一个结点的地址)。如果链表每个结点中只有一个指向后继结点的指针,则该链表称为单链表。
单链表
在结点之后插入一个结点
我们在插入一个结点的时候需要注意。第一步,让新结点的后继指针指向data2结点。保证链表后半截与新结点连接上。第二步,让data1的后继指针指向新结点。
template <class T>
void Node<T>::insertAfter(Node<T> *p) {
//p节点指针域指向当前节点的后继节点
p->next = next;
next = p; //当前节点的指针域指向p
}
删除结点之后的结点
删除结点,我们需要先将要删除的结点用指针保存起来,因为在删除的时候,并不能确定这个结点在其他地方时候还有用处,是释放内存,还是将该结点插入其他链表。另外,删除结点其实很简单,只需要把后继指针指向下一个结点就可以,如果后继指针为0,则说明链表到尾返回0.
Node<T> *Node<T>::deleteAfter(void) {
Node<T> *tempPtr = next;
if (next == 0)
return 0;
next = tempPtr->next;
return tempPtr;
}
完整程序如下
//Node.h
#ifndef NODE_H
#define NODE_H
//类模板的定义
template <class T>
class Node {
private:
Node<T> *next; //指向后继结点的指针
public:
T data; //数据域
Node (const T &data, Node<T> *next = 0); //构造函数
void insertAfter(Node<T> *p); //在本结点之后插入一个同类结点p
Node<T> *deleteAfter(); //删除本结点的后继结点,并返回其地址
Node<T> *nextNode(); //获取后继结点的地址
const Node<T> *nextNode() const; //获取后继结点的地址
};
//类的实现部分
//构造函数,初始化数据和指针成员
template <class T>
Node<T>::Node(const T& data, Node<T> *next = 0 ) : data(data), next(next) { }
//返回后继结点的指针
template <class T>
Node<T> *Node<T>::nextNode() {
return next;
}
//返回后继结点的指针
template <class T>
const Node<T> *Node<T>::nextNode() const {
return next;
}
//在当前结点之后插入一个结点p
template <class T>
void Node<T>::insertAfter(Node<T> *p) {
p->next = next; //p结点指针域指向当前结点的后继结点
next = p; //当前结点的指针域指向p
}
//删除当前结点的后继结点,并返回其地址
template <class T> Node<T> *Node<T>::deleteAfter() {
Node<T> *tempPtr = next;//将欲删除的结点地址存储到tempPtr中
if (next == 0) //如果当前结点没有后继结点,则返回空指针
return 0;
next = tempPtr->next;//使当前结点的指针域指向tempPtr的后继结点
return tempPtr; //返回被删除的结点的地址
}
#endif //NODE_H