含有哨兵节点的双链表
作者:
小小蒟蒻
,
2022-08-18 09:38:54
,
所有人可见
,
阅读 252
#ifndef __LIST_H__
#define __LIST_H__
#include <iostream>
#include <initializer_list>
template<typename DataType>
class list {
private:
struct Node {
DataType data;
Node* prev;
Node* next;
Node() { }
Node(const DataType& d) : data{ d }, prev{ nullptr }, next{nullptr} { }
};
private:
Node* head = nullptr;
Node* tail = nullptr;
int size = 0;
public:
list();
list(const list<DataType>& ls);
list(std::initializer_list<DataType> init_list);
~list();
const list<DataType>& operator=(const list<DataType>& ls);
DataType& operator[](int index);
DataType operator[](int index) const;
void insert(const DataType data, int pos);
void remove(const DataType data);
void remove_at(int index);
void append(DataType data);
void printList() const;
bool empty() const;
void clear();
int length() const;
private:
Node* get(int index) const;
Node* search(DataType data);
void append(Node* node);
void remove(Node* node);
};
template<typename DataType>
list<DataType>::list() {
head = new Node();
head->prev = head->next = nullptr;
tail = head;
size = 0;
}
template<typename DataType>
list<DataType>::list(const list<DataType>& ls) : list() {
std::cout << "拷贝构造\n" << std::endl;
Node* node = ls.head->next;
while (node != nullptr) {
append(node->data);
node = node->next;
}
}
template<typename DataType>
list<DataType>::list(std::initializer_list<DataType> init_list) : list() {
for (auto e : init_list)
append(e);
}
template<typename DataType>
list<DataType>::~list() {
std::cout << "~list()" << std::endl;
clear();
delete head;
tail = head = nullptr;
}
template<typename DataType>
const list<DataType>& list<DataType>::operator=(const list<DataType>& ls) {
std::cout << "=\n";
if (&ls == this)
return *this;
clear();
Node* node = ls.head->next;
while (node != nullptr) {
append(node->data);
node = node->next;
}
return *this;
}
template<typename DataType>
DataType& list<DataType>::operator[](int index) {
return get(index)->data;
}
template<typename DataType>
DataType list<DataType>::operator[](int index) const{
return get(index)->data;
}
template<typename DataType>
void list<DataType>::insert(const DataType data, int pos) {
if (pos > size ||pos < 0) {
std::cerr << "index out of bound\n";
exit(1);
}
if (pos == size) {
append(data);
}
else {
Node* node = get(pos);
Node* insert_node = new Node(data);
insert_node->next = node;
insert_node->prev = node->prev;
node->prev->next = insert_node;
node->prev = insert_node;
++size;
}
}
template<typename DataType>
void list<DataType>::remove(const DataType data) {
Node* node = search(data);
remove(node);
}
template<typename DataType>
void list<DataType>::remove_at(int index) {
remove(get(index));
}
template<typename DataType>
void list<DataType>::remove(Node* node) {
if (node == nullptr)return;
if (node == tail) {
node->prev->next = nullptr;
tail = node->prev;
}
else {
node->prev->next = node->next;
node->next->prev = node->prev;
}
delete node;
--size;
}
template<typename DataType>
void list<DataType>::append(DataType data) {
Node* node = new Node(data);
append(node);
}
template<typename DataType>
void list<DataType>::append(Node* node) {
if (head->next == nullptr) {
head->next = node;
node->prev = head;
tail = node;
}
else {
node->prev = tail;
tail->next = node;
tail = node;
}
++size;
}
template<typename DataType>
typename list<DataType>::Node* list<DataType>::get(int index) const{
if (index >= size || index < 0) {
std::cerr << "index out of bound\n";
exit(1);
}
int count;
Node* node;
if (index <= size / 2) {
count = 0;
node = head->next;
while (count++ < index)
node = node->next;
}
else {
count = size - 1;
node = tail;
while (count-- > index)
node = node->prev;
}
return node;
}
template<typename DataType>
typename list<DataType>::Node* list<DataType>::search(DataType data) {
Node* node = head->next;
while (node != nullptr) {
if (node->data == data)
return node;
node = node->next;
}
return nullptr;
}
template<typename DataType>
void list<DataType>::printList() const {
if (size <=0 )
return;
Node* node = head->next;
while (node != nullptr) {
std::cout << node->data << " ";
node = node->next;
}
std::cout << "length:" << length() << std::endl;
}
template<typename DataType>
bool list<DataType> ::empty() const {
return (size == 0);
}
template<typename DataType>
int list<DataType>::length() const {
return size;
}
template<typename DataType>
void list<DataType>::clear() {
Node* node = head->next;
while (node != nullptr) {
Node* tmp = node;
node = node->next;
delete tmp;
}
head->prev = head->next = nullptr;
size = 0;
}
#endif
#include "list.h"
#include <iostream>
int main() {
list<int> ls = { 1,2,3,4 };
ls.printList();
ls.append(5);
ls.printList();
ls.insert(0, 0);
ls.insert(ls.length(), 6);
ls.printList();
ls.remove(0);
ls.printList();
ls.remove_at(0);
ls.printList();
ls.remove_at(ls.length()-1);
ls.printList();
ls[2] = 1;
ls.printList();
const list<int> const_ls = { 1,2,3 };
std::cout << const_ls[2] << std::endl;
const_ls.printList();
list<int> ls1 = ls;
ls1.printList();
list<int> ls2;
ls2 = ls;
ls2.printList();
return 0;
}