单链表
链表是常用的数据结构,其优点是插入和删除元素时不需要移动,表的容量可扩充,且存储空间可以不连续。
另外,由于涉及到指针,所以很受面试官的青睐。
本文将主要介绍单链表,并简单介绍下双链表和环形链表,并通过一系列的题目来强化这方面的知识。
链表节点的结构:
template<class DataType>
struct Node
{
DataType data;
Node<DataType> *next;
};
data存放节点的数据,next指向下一个节点。
对于单链表,需要设置头指针,指向第一个元素所在的节点,所有的操作都是从头指针开始的。
有时候我们可以设置一个哨兵,它也是一个节点,称为头节点,该节点不存放数据,仅用于简化代码(加上头结点之后,无论链表是否为空,头指针始终指向头结点,因此空表和非空表的处理统一一点)。
下面我们将以有哨兵的链表为例来实现单链表。
template<class DataType>
class LinkList
{
public:
LinkList();
LinkList(DataType a[], int n);
~LinkList();
DataType get(int i); //按位查找,第i个节点
int locate(DataType x); //按值查找,返回x的位置序号
void insert(int i, DataType x); //在第i个位置插入x
DataType erase(int i);
void print();
private:
Node<DataType> *first; //头指针
};
构造函数
template<class DataType>
LinkList<DataType>::LinkList()
{
first = new Node<DataType>;
first->next = NULL;
}
//头插法
template<class DataType>
LinkList<DataType>::LinkList(DataType a[], int n)
{
first = new Node<DataType>;
first->next = NULL;
Node<DataType> *newNode;
for (int i = 0; i < n; ++i)
{
newNode = new Node<DataType>;
newNode->data = a[i];
newNode->next = first->next;
first->next = newNode;
}
}
//尾插法
template<class DataType>
LinkList<DataType>::LinkList(DataType a[], int n)
{
first = new Node<DataType>;
Node<DataType> *rail, *newNode;
rail = first;
for (int i = 0; i < n; ++i)
{
newNode = new Node<DataType>;
newNode->data = a[i];
rail->next = newNode;
rail = newNode;
}
rail->next = NULL;
}<