这里以结构体的方式来实现链表,也可以使用类。结构体在没有修饰符的情况下,默认是共有访问。如有不对,希望能指出。
目录
一、链表和结点结构体的声明 (ListNode.h)
typedef int data_t;
typedef struct ListNode { // 结点声明
data_t data;
ListNode* next;
ListNode* prev;
}ListNode;
typedef struct SeqLinkList {
SeqLinkList();
void list_print(); // 从前往后打印链表
void list_reverse_print(); // 从后往前打印链表
size_t size(); // 链表大小(链表结点个数)
int push_back(data_t val); // 尾插
void pop_back(); // 尾删
int push_front(data_t val); // 头插
int list_find(data_t val); // 查找某个结点
int list_insert(int pos, data_t val); // 在某个位置插入一个结点
int list_delete(int pos); // 删除某个位置的结点
void list_destroy(); // 释放整个链表
private:
ListNode* _phead; // 链表头结点的地址
ListNode* _ptail; // 链表尾结点的地址
size_t _num; // 链表元素的个数
}SeqLinkList;
二、链表各个功能的实现
1、增
(1) 构造函数(创建链表头结点)
创建一个空的头结点,同时初始化元素个数
SeqLinkList::SeqLinkList() {
_phead = (ListNode*)malloc(sizeof(ListNode));
assert(_phead);
_ptail = _phead; // 此时头尾指向同一个地方
_num = 0; // 初始化结点的个数
}
(2) 尾插
int SeqLinkList::push_back(data_t val) {
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
if (newNode == NULL)
return -1;
newNode->data = val;
newNode->next = NULL;
newNode->prev = _ptail;
_ptail->next = newNode; // 链接新的结点
_ptail = newNode; // 尾节点移动
_num++;
return 0;
}
(3) 头插
int SeqLinkList::push_front(data_t val) {
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
if (newNode == NULL)
return -1;
ListNode* nextNode = _phead->next; // _phead的下一个结点
newNode->data = val;
newNode->next = nextNode;
newNode->prev = _phead;
_phead->next = newNode;
if (nextNode != NULL)
nextNode->prev = newNode;
_num++;
return 0;
}
(4) 任意位置的插入
int SeqLinkList::list_insert(int pos, data_t val) {
if (pos > _num - 1)
return -1;
ListNode* current = _phead;
while (pos-- && (current = current->next) != NULL);
ListNode* nextNode = current->next; // 记录下当前节点的下一个结点
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
if (newNode == NULL)
return -1;
newNode->data = val; // 链接新的结点
current->next = newNode;
newNode->next = nextNode;
newNode->prev = current;
if (nextNode != NULL)
nextNode->prev = newNode; // 考虑尾插
_num++;
return 0;
}
2、删
(1) 尾删
void SeqLinkList::pop_back() {
ListNode* tailNode = _ptail; // 记录尾节点
_ptail = _ptail->prev;
_ptail->next = NULL;
free(tailNode);
tailNode = NULL;
_num--;
}
(2) 任意位置的删除
int SeqLinkList::list_delete(int pos) {
if (pos > _num - 1)
return -1;
ListNode* current = _phead;
while (pos-- && (current = current->next) != NULL);
if (current == _phead)
_phead = current->next; // 考虑头删
else
{
ListNode* prevNode = current->prev;
ListNode* nextNode = current->next;
prevNode->next = nextNode;
if (nextNode != NULL)
nextNode->prev = prevNode;
}
free(current);
current = NULL;
_num--;
return 0;
}
(3) 链表释放
void SeqLinkList::list_destroy() {
_num++; // 补上一个头结点,下面是连带着头结点一起释放了
while (_phead != NULL)
{
ListNode* lastNode = _phead;
_phead = _phead->next;
free(lastNode);
lastNode = NULL;
_num--;
}
}
3、查
(1) 获取元素个数
size_t SeqLinkList::size() {
return _num;
}
(2) 正向打印
void SeqLinkList::list_print(){
ListNode* current = _phead;
while ((current = current->next) != NULL)
{
printf("%d->", current->data);
}
}
(3) 反向打印
void SeqLinkList::list_reverse_print() {
ListNode* current = _ptail;
while (current != _phead)
{
printf("%d->", current->data);
current = current->prev;
}
}