链表简介
链表和数组一样也是一种线性数据结构。
链表一般以链式存储结构实现,适合需要频繁增删数据的需求,但是不支持随机访问。
链表一般包括单链表和双链表以及循环链表,单链表和双链表以及循环链表的实现一般使用虚拟头结点的形式可以简化实现细节。
在C++ STL标准库中,<list>头文件实现的为双链表,<forward_list>头文件实现的为单链表形式。
单链表
单链表的节点包含数据值和指向下一个节点的next指针,最后一个节点的next指针指向nullptr指针。
双链表
双链表的节点包含数据值和指向下一个节点的next指针以及指向前一个节点的prev指针。
链表实现
单链表和双链表均使用含有虚拟头结点的形式。
单链表实现
#ifndef MYLIST_H
#define MYLIST_H
#include<assert.h>
using namespace std;
template<typename T>
class mylist
{
public:
//两种链表构造函数
mylist()
{
dummynode = new node;
}
mylist(T data)
{
dummynode = new node;
node* newnode= new node;
dummynode->next = newnode;
newnode->data = data;
count++;
}
//判断链表是否为空
bool empty()
{
return count == 0;
}
//判断链表存储数据容量
int size()
{
return count;
}
//在链表指定位置处添加新节点
void add(int index, T data)
{
assert(index >= 0 && index <= count);
node* prev = dummynode;
for (int i = 0; i < index; i++)
{
prev = prev->next;
}
node* newnode = new node(data);
newnode->next = prev->next;
prev->next = newnode;
count++;
}
//在链表执行位置处删除节点
void remove(int index)
{
assert(index >= 0 && index < count);
node* prev = dummynode;
for (int i = 0; i < index; i++)
prev = prev->next;
node* tmp = prev->next;
prev->next = tmp->next;
tmp->next = nullptr;
delete tmp;
count--;
}
//判断链表中是否包含指定数据
bool contain(T data)
{
node* tmp = dummynode;
while (tmp->next != nullptr)
{
if (tmp->data == data)
return true;
tmp = tmp->next;
}
return false;
}
//获取指定位置处的数据
T get(int index)
{
assert(index >= 0 && index < count);
node* getnode = dummynode;
for (int i = 0; i <= index; i++)
{
getnode = getnode->next;
}
return getnode->data;
}
//析构函数
~mylist()
{
node* tmp;
tmp = dummynode->next;
delete dummynode;
while (tmp != nullptr)
{
node* deletetmp = tmp;
tmp = tmp->next;
delete deletetmp;
}
}
private:
//链表节点的定义
struct node
{
node(T data,node*next) : data(data),next(next) {}
node(T data) : data(data),next(nullptr) {}
node():data(NULL),next(nullptr) {}
T data;
node* next;
};
int count = 0;
node* dummynode;
};
#endif
双链表的实现
#ifndef DBLINKEDLIST_H
#define DBLINKEDLIST_H
#include<assert.h>
using namespace std;
template<typename T>
class dblinkedlist
{
public:
//链表构造函数
dblinkedlist()
{
dummynode = new node;
}
dblinkedlist(T data)
{
dummynode = new node;
node* newnode = new node;
dummynode->next = newnode;
newnode->prev = dummynode;
newnode->data = data;
count++;
}
//判断链表是否为空
bool empty()
{
return count == 0;
}
//判断链表大小
int size()
{
return count;
}
//在链表中增加节点
void add(int index, T data)
{
assert(index >= 0 && index <= count);
node * pre = dummynode;
for (int i = 0; i < index; i++)
{
pre = pre->next;
}
node* newnode = new node(data);
if (index == count)
{
pre->next = newnode;
newnode->prev = pre;
count++;
return;
}
pre->next->prev = newnode;
newnode->next = pre->next;
newnode->prev = pre;
pre->next = newnode;
count++;
}
//在链表中删除节点
void remove(int index)
{
assert(index >= 0 && index < count);
node * pre = dummynode;
for (int i = 0; i < index; i++)
pre = pre->next;
node * tmp = pre->next;
if (index == count - 1)
{
pre->next = nullptr;
tmp->prev = nullptr;
delete tmp;
count--;
return;
}
tmp->next->prev = pre;
pre->next = pre->next->next;
tmp->next = nullptr;
tmp->prev = nullptr;
delete tmp;
count--;
}
//判断链表中是否包含指定数据
bool contain(T data)
{
node* tmp = dummynode;
while (tmp->next != nullptr)
{
if (tmp->data == data)
return true;
tmp = tmp->next;
}
return false;
}
//获取链表指定位置处的数据
T get(int index)
{
assert(index >= 0 && index < count);
node * getnode = dummynode;
for (int i = 0; i <= index; i++)
{
getnode = getnode->next;
}
return getnode->data;
}
//析构函数
~dblinkedlist()
{
node* tmp;
tmp = dummynode->next;
delete dummynode;
while (tmp != nullptr)
{
node* deletetmp = tmp;
tmp = tmp->next;
delete deletetmp;
}
}
private:
//双向链表节点
struct node
{
node(T data, node* next,node* prev) : data(data), next(next), prev(prev) {}
node(T data) : data(data), next(nullptr), prev(nullptr) {}
node() :data(NULL), next(nullptr), prev(nullptr) {}
T data;
node* next;
node* prev;
};
int count = 0;
node* dummynode;
};
#endif