c++实现不带头结点的双向非循环链表(代码即注释,超详细版)
直接上代码
#include <iostream>
using namespace std;
class Node
{
public:
int _data;
Node *_pre;
Node *_next;
// 初始化节点
Node(int data = 0) : _data(data), _pre(nullptr), _next(nullptr)
{
// cout << "Node()" << endl;
}
~Node()
{
// cout << "~Node()" << endl;
}
};
class List
{
private:
Node *_head;
Node *_tail;
int _size;
public:
// 初始话链表
List() : _head(nullptr), _tail(nullptr), _size(0)
{
// cout << "List()" << endl;
}
// 不带头节点的非循环双向链表头部插入操作
void headInsertNode(int data)
{
// 如果此时链表为空,插入第一个节点
if (0 == _size)
{
// 申请空间,将头尾指针指向该节点,链表大小加1
Node *newNode = new Node(data);
_head = newNode;
_tail = newNode;
++_size;
}
else
{
Node *newNode = new Node(data);
newNode->_next = _head; // 新节点插入到头节点前
_head->_pre = newNode;
_head = newNode; // 头指针指向新插入的节点
++_size;
}
}
//尾部插入
void tailInsertNode(int data)
{
if (0 == _size)
{
Node *newNode = new Node(data);
_head = newNode;
_tail = newNode;
++_size;
}
else
{
Node *newNode = new Node(data);
_tail->_next = newNode;
newNode->_pre = _tail;
_tail = newNode; // 尾指针指向新插入的节点
++_size;
}
}
// 指定位置插入数据,插入元素data到第pos的位置
int posInsert(int pos, int data)
{
// 判断非法位置
if (pos < 1 || pos > (_size + 1))
{
cout << "posInsert(" << pos << ", " << data << "): error pos!" << endl;
return -1;
}
// 如果插入位置是1,表示插在链表最开始位置
if (1 == pos)
{
headInsertNode(data);
}
// 如果插入位置是链表的长度+1,表示插在链表的最后面
else if (_size + 1 == pos)
{
tailInsertNode(data);
}
else
{
// 偏移指针到指定位置
Node *pIns = _head;
while ((--pos) > 1)
{
cout << "pos = " << pos << endl;
pIns = pIns->_next;
}
// 申请新的节点空间
Node *newNode = new Node(data);
newNode->_next = pIns->_next;
newNode->_pre = pIns;
pIns->_next->_pre = newNode;
pIns->_next = newNode;
++_size;
}
return 0;
}
// 从头部删除元素
void deleteHead()
{
// 判断链表是否为空,空则无法删除数据
if (_size)
{
Node *pDel = _head;
_head = _head->_next;
delete pDel;
pDel = nullptr;
--_size;
}
else
{
cout << "list is empty, can not delete any data!" << endl;
}
}
// 从尾部删除元素
void deleteTail()
{
if (_size)
{
Node *pDel = _tail;
_tail = _tail->_pre;
delete pDel;
pDel = nullptr;
--_size;
}
else
{
cout << "list is empty, can not delete any data!" << endl;
}
}
// 删除指定位置元素,
int posDelete(int pos)
{
// 判断非法位置
if (pos < 1 || pos > _size)
{
cout << "posDelete(" << pos << "): error pos!" << endl;
return -1;
}
if (1 == pos)
{
deleteHead();
}
else if (_size == pos)
{
deleteTail();
}
else
{
// 将指针指向头节点,准备进行偏移到待删除位置
Node *pDel = _head;
while ((pos--) > 1)
{
pDel = pDel->_next;
}
pDel->_pre->_next = pDel->_next;
pDel->_next->_pre = pDel->_pre;
delete pDel;
pDel = nullptr;
--_size;
}
return 0;
}
// 打印节点,从头开始打印
void printList()
{
// cout << "list size = " << _size << endl;
if (_size)
{
Node *pNode = _head;
cout << "链表元素: ";
for (int i = 0; i < _size; ++i)
{
cout << pNode->_data << " ";
pNode = pNode->_next;
}
cout << endl;
}
else
{
cout << "empty list!" << endl;
}
}
int listSize() const
{
return _size;
}
void findNode(int data)
{
if (_size)
{
Node *findNode = _head;
while (findNode->_next)
{
if (data == findNode->_data)
{
cout << data << " is in the list!" << endl;
return;
}
findNode = findNode->_next;
}
cout << data << " is not in the list!" << endl;
}
}
~List()
{
// cout << "~List()" << endl;
// 从头到尾依次删除节点,并释放空间
while (_size)
{
Node *deleteNode = _head;
_head = _head->_next;
delete deleteNode;
deleteNode = nullptr;
_size--;
}
}
};
int main(int argc, char **argv)
{
List lt;
lt.printList();
lt.tailInsertNode(10);
lt.headInsertNode(11);
lt.tailInsertNode(9);
lt.printList();
lt.posInsert(0, 1);
lt.printList();
lt.posInsert(1, 2);
lt.printList();
lt.posInsert(2, 3);
lt.printList();
lt.findNode(11);
lt.findNode(12);
cout << "list size = " << lt.listSize() << endl;
lt.posDelete(6);
lt.printList();
lt.posDelete(1);
lt.printList();
lt.deleteHead();
lt.printList();
return 0;
}
运行结果:
empty list!
链表元素: 11 10 9
posInsert(0, 1): error pos!
链表元素: 11 10 9
链表元素: 2 11 10 9
链表元素: 2 3 11 10 9
11 is in the list!
12 is not in the list!
list size = 5
posDelete(6): error pos!
链表元素: 2 3 11 10 9
链表元素: 3 11 10 9
链表元素: 11 10 9
本人能力有限,如有错误望不吝指正,原创不易,欢迎转载,转载请注明出处