在单向链表的删除操作中,如果要从链表尾部删除一个节点,需要用循环找到 tail 前面的节点实现节点去除。对于较长的链表和频繁执行尾部删除的情况来说,这是一个影响处理速度的障碍。为了避免这个问题,可以对单向链表进行重新定义,使链表中的每个节点有两个节点,一个指向前驱,一个指向后继,这种链表被称为双向链表。
用 C++ 对双向链表进行构建。
//linked_lists.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
using std::ostream;
using std::cout;
using std::endl;
class Double_linked_list_node
{
public:
int info;
Double_linked_list_node *prev, *next;
public:
Double_linked_list_node()
{
info = 0;
prev = nullptr;
next = nullptr;
}
Double_linked_list_node(int i = 0, Double_linked_list_node *p = nullptr,
Double_linked_list_node *q = nullptr)
{
info = i;
prev = p;
next = q;
}
~Double_linked_list_node() {};
};
class Double_linked_list
{
public:
Double_linked_list_node *head, *tail;
public:
Double_linked_list()
{
head = tail = nullptr;
}
bool isempty()
{
return head == nullptr;
}
bool inlist(int);
void addtohead(int);
void addtotail(int);
int deletefromhead();
int deletefromtail();
void deleteselect(int);
friend ostream & operator<<(ostream&, const Double_linked_list &);
~Double_linked_list();
};
#endif // !LINKED_LIST_H
// linked_lists.cpp
#include <iostream>
#include "linked_lists.h"
bool Double_linked_list::inlist(int i)
{
Double_linked_list_node *tmp;
if (head == nullptr)
return 0;
else if (head == tail)
return (head->info) == i;
else
{
for (tmp = head; tmp != nullptr && !(tmp->info == i); tmp = tmp->next);
return tmp != nullptr;
}
}
void Double_linked_list::addtohead(int i)
{
if (head == nullptr)
{
head = new Double_linked_list_node(i); // 此处应该创建一个新的节点,并让head指向它
tail = head;
}
else
head = new Double_linked_list_node(i, nullptr, head), head->next->prev = head;
}
void Double_linked_list::addtotail(int i)
{
if (head == nullptr)
{
head = tail = new Double_linked_list_node(i);
}
else
tail = new Double_linked_list_node(i, tail, nullptr), tail->prev->next = tail;
}
int Double_linked_list::deletefromhead()
{
int i;
if (head == nullptr)
return 0;
else
{
i = head->info;
if (head == tail)
head = tail = nullptr;
else
head = head->next, delete head->prev,head->prev = nullptr;
return i;
}
}
int Double_linked_list::deletefromtail()
{
int i;
if (head == nullptr)
return 0;
else
{
i = tail->info;
if (head == tail)
head = tail = nullptr;
else
tail = tail->prev, delete head->prev,tail->next = nullptr;
return i;
}
}
void Double_linked_list::deleteselect(int i)
{
Double_linked_list_node *tmp;
if (head != nullptr)
if (head == tail)
if (head->info == i)
head = tail = nullptr;
else
;
else
{
for (tmp = head; tmp != nullptr && !(tmp->info == i); tmp = tmp->next) // 这里需要表明tmp!=nullptr
;
if (tmp != nullptr)
tmp->prev->next = tmp->next, tmp->next->prev = tmp->prev, delete tmp;
}
}
ostream & operator<<(ostream& out, const Double_linked_list & p)
{
Double_linked_list_node *tmp;
for (tmp = p.head; tmp != nullptr; tmp = tmp->next)
out << tmp->info << " ";
return out;
}
Double_linked_list::~Double_linked_list()
{
for (Double_linked_list_node *tmp; !isempty();)
{
tmp = head->next;
delete head;
head = tmp;
}
}
// create_list.cpp
#include <iostream>
#include "linked_lists.h"
int main()
{
using namespace std;
//*********此处是双向链表测试代码********
Double_linked_list list2;
cout << list2.isempty() << endl;
list2.addtohead(1);
list2.addtohead(2);
list2.addtohead(3);
list2.addtohead(4);
list2.addtotail(5);
list2.addtotail(6);
list2.addtotail(7);
list2.addtotail(8);
list2.deletefromhead();
list2.deletefromhead();
list2.deletefromtail();
list2.deletefromtail();
list2.deleteselect(5);
list2.deleteselect(12);
cout << list2.inlist(1) << endl;
cout << list2.inlist(10) << endl;
cout << list2.isempty() << endl;
cout << list2 << endl;
//***********************************/
system("pause");
return 0;
}
参考资料:
1. C++数据结构与算法:https://item.jd.com/29739898993.html