C++: 实现双向链表(例题讲解)
标签: C++ 双向链表
by 小威威
这一周的实验题比较水,我就不总结了,而作业题中最有意思的就是实现双向链表这一道题。
这道题和我们之前做的单向链表是同一种类型的,只是这一次是双向链表,需要实现的操作较多,可能产生的bug也比之前多。我个人觉得,打出这道题的代码不难,难是难在调试。
(入门链表的可以参照我以前的一篇文档入门:链表的基本操作)
题目如下:(Author: 叶嘉祺(TA))
Introduction
Well, this time we will be a little difficult for you to do. We are going to design a link list class in c++. Again, the knowledge of pointer in c++ in widely used this time and you have to focus when you are coding. List is not easy for you.
Knowledge
This time, you are going to finish a advanced list which is known as doubly linked list. Each node of the list have three members: data which is use as the real storage, next pointer which is used to linked the next node of the list, prev pointer which is use to linked the previous node.
Requirements
Finish the member functions below.
Notice that for output functions, the format is as below:
toString() [1,2,3,4,5]
NULL<-1<->2<->3<->4<->5->NULL
toString() []
NULL
toString() [1]
NULL<-1->NULL
No new line is needed;
void split(int position, list* des1, list* dest2) 2 [1,2,3,4]
[1,2] [3,4]
list& merge(const list& src1, const list& src2) [1,2,3,4] [5,6,7,8]
[1,2,3,4,5,6,7,8]
list& remove_if(bool (*condition)(listPointer)); [1,2,3,4,5,6] condition = odd number
[2,4,6]
list& unique(void) [1,2,2,3,4,4,5,6]
[1,2,3,4,5,6]
list& reverse(void) [1,2,3,4,5,6]
[6,5,4,3,2,1]
下面是双向链表的简要模型:
题目的main.cpp 与 List.hpp 已经给出。
// main.cpp
#include "List.hpp"
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
bool condition1(list::listPointer p) { return true; }
bool condition2(list::listPointer p) {
if (p->data % 2 == 0) {
return false;
}
return true;
}
bool condition3(list::listPointer p) {
if (p->data > 5) {
return false;
}
return true;
}
void outputList(const list& li) {
cout << li << " size:" << li.size();
if (&li.front() == NULL) {
cout << " front:NULL";
} else {
cout << " front:" << li.front();
}
if (&li.back() == NULL) {
cout << " back:NULL";
} else {
cout << " back:" << li.back();
}
cout << endl;
}
int main() {
int n, m;
cin >> n >> m;
int* a = new int[n]();
for (int i = 0; i < n; i++) {
cin >> a[i];
}
if (true) {
list li1(a, n);
li1.insert(2, 111);
li1.push_front(150);
list li2(li1);
outputList(li1);
outputList(li2);
}
cout << endl;
if (true) {
list li1;
for (int i = 0; i < n; i++) {
li1.insert(i, a[i]);
}
for (int i = 0; i < m; i++) {
li1.erase(i);
}
outputList(li1);
}
cout << endl;
if (true) {
list li1(a, n), li2, li3;
li1 = li2 = li3 = li1;
outputList(li1);
li1.split(0, &li2, &li3);
outputList(li1);
outputList(li2);
outputList(li3);
li1.split(li1.size(), &li2, &li3);
outputList(li1);
outputList(li2);
outputList(li3);
li1.split(li1.size() / 2, &li2, &li3);
cout << li2.toString() << endl;
cout << li3.toString() << endl;
li1 += (li2 += li1).merge(li1, li1);
outputList(li1);
li1 += li3;
li2.merge(li1, li3);
for (int i = 0; i < li1.size(); i++) {
cout << li1[i] << " ";
}
cout << endl;
outputList(li2);
}
cout << endl;
cout << endl;
if (true) {
list li1(a, n);
li1.remove_if(condition1);
cout << li1 << " " << endl;
li1.assign(a, n);
li1.remove_if(condition2);
cout << li1 << endl;
li1.assign(a, n);
li1.remove_if(condition3);
outputList(li1);
}
cout << endl;
if (true) {
list li(a, n);
li.merge(li, li).merge(li, li).unique();
outputL