C++双向链表的实现

#include <iostream>
#include <assert.h>
using namespace std;
typedef int DataType;
// 首先要明白一个链表的组成,链表又结点连接起来构成,我们定义出一个结点的结构体,每一个结点都有自己的next域,pre 域,以及自身的数据。
struct Node
{
Node( const DataType& data = DataType())
:_next(NULL)
, _pre(NULL)
, _data(data)
{}

Node *_next;
Node *_pre;
DataType _data;
};
// 创建链表结构体的时候,要清楚,一个链表会有自己的头指针,尾指针,还有链表的结点数。我们把链表的头,尾指针都定义为Node*类型。
class List
{
public:
List()//空链表的构造函数
:_pHead(NULL)
, _pTail(NULL)
, _size(0)
{}
Node *_pHead;
Node *_pTail;
size_t _size;
List(size_t n, const DataType & data = DataType())//明确给出构造n个结点,并且每个结点的值为默认值
:_pHead(NULL)
, _pTail(NULL)
, _size(0)
{
/*_pHead = _pTail = new Node(data);//我们可以用这样的方式来构造出一条链表
for (size_t idx = 0; idx < n - 1; idx++)
{
Node*pCur = new Node(data);
_pTail->_next = pCur;
pCur->_pre = _pTail;
_pTail = pCur;
}*/
for (size_t idx = 0; idx < n; idx++)//直接用尾插法创建链表
{
PushBack(data);
}

}
bool Empty()const//判断链表是否为空,因为后面的好多地方都要用到这些代码,为了提高代码的复用率,直接封装一个函数。
{
return (NULL == _pHead);
}
void PushBack(const DataType &data)
{
Node* pNode = new Node(data);
if (Empty())
{
_pHead = _pTail = pNode;

}
else
{
_pTail->_next = pNode;
pNode->_pre = _pTail;
_pTail = pNode;
}
_size++;

}
void PopBack(const DataType& data)
{
if (Empty())
{
assert(false);
return;
}
else if (_pHead=_pTail)//只有一个结点;
{
delete _pHead;
_pHead = _pTail = NULL;
   
}
else
{
_pTail = _pTail->_pre;
delete _pTail->_next;
_pTail->_next = NULL;
}
--_size;
}
void PushFront(const DataType& data)
{
Node*pNode = new Node(data);
if (Empty())
{
_pHead = _pTail = pNode;

}
else
{
pNode->_next = _pHead;
_pHead->_pre = pNode;
_pHead = _pHead->_pre;
}
_size++;
}
void PopFront()
{
if (Empty())
{
assert(false);
return;
}
else if (_size == 1)
{
delete _pHead;
_pHead = _pTail = NULL;
}
else
{
_pHead = _pHead->_next;
delete _pHead->_pre;
_pHead->_pre = NULL;
}
_size--;
}
Node*find(const DataType &data)
{
Node * pCur = _pHead;
while (pCur)
{
if (pCur->_data = data)
return pCur;
pCur = pCur->_next;
}
return NULL;
}
size_t Size()const
{
return _size;
}

DataType& Front()
{
return _pHead->_data;
}

const DataType& Front()const
{
return _pHead->_data;
}

DataType& Back()
{
return _pTail->_data;
}

const DataType& Back()const
{
return _pTail->_data;
}
void print_List()
{
Node*phead = _pHead;
while (phead){
cout << phead->_data << "->" << endl;
phead = phead->_next;
}
}
void insert(Node* pos, DataType x)
{
assert(pos);//防止pos为空指针  
if (Empty())
{
return;
}
else
{
Node* pCur = _pHead;
if (_pHead == pos)
{
PushFront(x);
}
else
{
while (pCur)
{
if (pCur == pos)
{
Node* tmp = new Node[sizeof(Node)];
tmp->_data = pCur->_data;
tmp->_next = pCur->_next;
tmp->_pre = pCur;
pCur->_data = x;
pCur->_next = tmp;
return;//insert成功后不要忘了直接返回结束函数  
}
pCur = pCur->_next;
}
cout << "没有找到这个数字" << endl;
}
}
}

void erase(Node* pos)//删除指定位置的结点  
{
assert(pos);
if (Empty())
{
return;
}
else
{
if (pos == _pHead)
{
PopFront();
}
else
{
Node* del = _pHead->_next;
Node* pre = _pHead;
while (del)
{
if (del == pos)
{
if (del->_next != NULL)
{
pre->_next = del->_next;
del->_next->_pre = pre;
delete del;
del = NULL;
}
else
{
delete del;
pre->_next = NULL;
}
return;
}
del = del->_next;
pre = pre->_next;
}
}
}
}

};
以下是使用 C++ 实现双向链表的通讯录的示例代码: ```c++ #include <iostream> #include <string> using namespace std; // 定义联系人结构体 struct Contact { string name; string phone; }; // 定义双向链表节点结构体 struct ListNode { Contact data; ListNode* prev; ListNode* next; ListNode(Contact value): data(value), prev(nullptr), next(nullptr) {} }; // 定义双向链表类 class DoubleLinkedList { private: ListNode* head; ListNode* tail; int size; public: DoubleLinkedList(): head(nullptr), tail(nullptr), size(0) {} ~DoubleLinkedList() { ListNode* p = head; while (p != nullptr) { ListNode* q = p->next; delete p; p = q; } head = tail = nullptr; size = 0; } void append(Contact value) { ListNode* node = new ListNode(value); if (tail == nullptr) { head = tail = node; } else { tail->next = node; node->prev = tail; tail = node; } size++; } void remove(ListNode* node) { if (node == nullptr) return; if (node == head) { head = head->next; if (head != nullptr) { head->prev = nullptr; } else { tail = nullptr; } } else if (node == tail) { tail = tail->prev; if (tail != nullptr) { tail->next = nullptr; } else { head = nullptr; } } else { node->prev->next = node->next; node->next->prev = node->prev; } delete node; size--; } void print() { ListNode* p = head; while (p != nullptr) { cout << "Name: " << p->data.name << ", Phone: " << p->data.phone << endl; p = p->next; } } int getSize() { return size; } }; int main() { DoubleLinkedList contacts; Contact c1 = {"Alice", "123456789"}; Contact c2 = {"Bob", "234567890"}; Contact c3 = {"Charlie", "345678901"}; contacts.append(c1); contacts.append(c2); contacts.append(c3); contacts.print(); cout << "Size: " << contacts.getSize() << endl; // 删除 Bob 的联系方式 ListNode* p = contacts.head; while (p != nullptr) { if (p->data.name == "Bob") { contacts.remove(p); break; } p = p->next; } contacts.print(); cout << "Size: " << contacts.getSize() << endl; return 0; } ``` 上述代码实现了一个基本的双向链表类,其中节点结构体 `ListNode` 包括了联系人结构体 `Contact` 和前驱节点和后继节点指针。在主函数中,我们创建了三个联系人并添加到双向链表中,然后打印出链表中所有联系人的信息。接着,我们使用循环遍历链表,找到名字为 Bob 的联系人并删除它,最后再次打印出链表中剩余的联系人信息和链表大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值