赞
踩
双链表节点由存储的数据、指向前一个元素的指针和指向后一个元素的指针构成,因此双联表节点的代码也很容易得到,如下:
// 双链表节点
struct DoubleListNode {
int data;
DoubleListNode* prev;
DoubleListNode* next;
DoubleListNode(int val);
};
双链表和单链表类似,也需要添加、删除和查找。
// 双链表
class DoubleList {
public:
DoubleListNode* dummy;
public:
DoubleList();
~DoubleList();
public:
void add(int);
void remove(int);
DoubleListNode* find(int);
};
插入的情况说明:插入每次都在第一个位置插入,也就是在伪头节点(不含元素)后插入。
插入节点的过程:
next
指向dummy
的下一个节点prev
指向dummy
节点。dummy
的下一个节点的prev
指针指向目标节点(如果后面没有元素则省略)dummy
节点的next
指针指向目标节点插入的代码逻辑:
void DoubleList::add(int val) {
auto ptr = find(val);
if (ptr) {
std::cerr << val << "exists, add failed!" << std::endl;
} else {
auto temp = new DoubleListNode(val);
temp->next = dummy->next;
temp->prev = dummy;
if (dummy->next)
dummy->next->prev = temp;
dummy->next = temp;
}
}
prev
指针指向目标节点的前一个节点(目标节点下一个节点不存在则省略)next
指针指向目标节点的下一个节点代码逻辑:
delete
void DoubleList::remove(int val) {
auto ptr = find(val);
if (ptr == nullptr) {
std::cerr << val << " does not exist, remove failed!" << std::endl;
} else {
if (ptr->next)
ptr->next->prev = ptr->prev;
ptr->prev->next = ptr->next;
delete ptr;
}
}
不同于单链表,双链表查找直接返回目标节点,对于删除操作十分方便。逻辑基本与单链表一致。
代码逻辑:
nullptr
DoubleListNode* DoubleList::find(int val) {
auto temp = dummy->next;
while (temp) {
if (temp->data == val)
return temp;
temp = temp->next;
}
return nullptr;
}
循环链表的不同之处:
循环链表在初始化时,伪头节点的prev
和next
指针都指向本身。经理各种操作过后,链表的最后一个节点的next
指针指向dummy
,伪头节点的prev
指针指向最后一个节点。
链表改为循环链表之后,添加删除操作都没影响,只有在构造以及一些需要判断链表是否到尾部的地方(如查找、析构、和测试代码)
循环链表的查找代码:
DoubleListNode* DoubleList::find(int val) {
auto temp = dummy->next;
while (temp != dummy) { // 改为不等于dummy节点
if (temp->data == val)
return temp;
temp = temp->next;
}
return nullptr;
}
// DoubleList.h双链表类定义 // 双链表节点 struct DoubleListNode { int data; DoubleListNode* prev; DoubleListNode* next; DoubleListNode(int val); }; // 双链表 class DoubleList { public: DoubleListNode* dummy; public: DoubleList(); ~DoubleList(); public: void add(int); void remove(int); DoubleListNode* find(int); };
// DoubleList.cpp双链表成员函数实现 #include <iostream> #include "DoubleList.h" DoubleListNode::DoubleListNode(int val) : data(val), prev(nullptr), next(nullptr) { } DoubleList::DoubleList() : dummy(new DoubleListNode(-1)) { dummy->prev = nullptr; dummy->next = nullptr; } DoubleList::~DoubleList() { auto ptr = dummy->next; while (ptr) { auto temp = ptr; ptr = ptr->next; delete temp; std::cout << "Element Deleted!" << std::endl; } delete dummy; std::cout << "DoubleList destoryed!" << std::endl; } void DoubleList::add(int val) { auto ptr = find(val); if (ptr) { std::cerr << val << "exists, add failed!" << std::endl; } else { auto temp = new DoubleListNode(val); temp->next = dummy->next; temp->prev = dummy; if (dummy->next) dummy->next->prev = temp; dummy->next = temp; } } void DoubleList::remove(int val) { auto ptr = find(val); if (ptr == nullptr) { std::cerr << val << " does not exist, remove failed!" << std::endl; } else { if (ptr->next) ptr->next->prev = ptr->prev; ptr->prev->next = ptr->next; delete ptr; } } DoubleListNode* DoubleList::find(int val) { auto temp = dummy->next; while (temp) { if (temp->data == val) return temp; temp = temp->next; } return nullptr; }
// DoubleListTest.cpp 双链表测试代码 #include <iostream> #include "DoubleList.h" int main(void) { DoubleList list; list.add(0); list.add(1); list.add(2); list.add(3); list.add(4); list.add(4); // 添加已存在元素 list.remove(0); // 末尾元素 list.remove(2); // 中间元素 list.remove(4); // 开头元素 list.remove(4); // 删除不存在元素 for (auto temp = list.dummy->next; temp; temp = temp->next) std::cout << temp->data << " "; std::cout << std::endl; /*期望的输出 4 exists, add failed! 4 does not exist, remove failed! 3 1 Element deleted! Element deleted! DoubleList Destroyed! */ return 0; }
// DoubleList.h 双循环链表类定义 // 双链表节点 struct DoubleListNode { int data; DoubleListNode* prev; DoubleListNode* next; DoubleListNode(int val); }; // 双链表 class DoubleList { public: DoubleListNode* dummy; public: DoubleList(); ~DoubleList(); public: void add(int); void remove(int); DoubleListNode* find(int); };
// DoubleList.cpp 双循环链表成员函数实现 #include <iostream> #include "DoubleList.h" DoubleListNode::DoubleListNode(int val) : data(val), prev(nullptr), next(nullptr) { } DoubleList::DoubleList() : dummy(new DoubleListNode(-1)) { dummy->prev = dummy; // nullptr改为dummy dummy->next = dummy; // nullptr改为dummy } DoubleList::~DoubleList() { auto ptr = dummy->next; while (ptr != dummy) { // 改为不等于dummy auto temp = ptr; ptr = ptr->next; delete temp; std::cout << "Element deleted!" << std::endl; } delete dummy; std::cout << "DoubleList destoryed!" << std::endl; } void DoubleList::add(int val) { auto ptr = find(val); if (ptr) { std::cerr << val << "exists, add failed!" << std::endl; } else { auto temp = new DoubleListNode(val); temp->next = dummy->next; temp->prev = dummy; if (dummy->next) dummy->next->prev = temp; dummy->next = temp; } } void DoubleList::remove(int val) { auto ptr = find(val); if (ptr == nullptr) { std::cerr << val << " does not exist, remove failed!" << std::endl; } else { if (ptr->next) ptr->next->prev = ptr->prev; ptr->prev->next = ptr->next; delete ptr; } } DoubleListNode* DoubleList::find(int val) { auto temp = dummy->next; while (temp != dummy) { // 改为不等于dummy if (temp->data == val) return temp; temp = temp->next; } return nullptr; }
// DoubleListTest.cpp 双链表测试代码 #include <iostream> #include "DoubleList.h" int main(void) { DoubleList list; list.add(0); list.add(1); list.add(2); list.add(3); list.add(4); list.add(4); // 添加已存在元素 list.remove(0); // 末尾元素 list.remove(2); // 中间元素 list.remove(4); // 开头元素 list.remove(4); // 删除不存在元素 for (auto temp = list.dummy->next; temp != list.dummy; temp = temp->next) std::cout << temp->data << " "; std::cout << std::endl; /*期望的输出 4 exists, add failed! 4 does not exist, remove failed! 3 1 Element deleted! Element deleted! DoubleList Destroyed! */ return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。