Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 6

### Double-linked list

#DynamicStructure
[[Linked List]] [[Linked List.Clear]] [[Linked List.Final]] [[Linked List Double
(!!!)]]

---
# Theory
---

## Overview

A double-linked list is a linear data structure in which each element is a separate


object containing a pointer to the previous element and a pointer to the next
element. Unlike arrays, linked lists do not have a fixed size and their size can
change dynamically during the execution of a program.

## Double-linked list
![[Pasted image 20230317180128.png]]

## Node Class

A node class is needed to represent each element in the list. The node class will
contain the data and two pointers - one to the next node and one to the previous
node. Here's an example implementation:
```cpp
template<typename T>
class Node {
public:
T data;
Node<T>* next;
Node<T>* prev;

Node(T val) {
data = val;
next = nullptr;
prev = nullptr;
}
};
```

## List Class

The list class will contain a pointer to the head and tail of the list, as well as
the size of the list. Here's an example implementation of the list class:
```cpp
template<typename T>
class DoubleLinkedList {
public:
DoubleLinkedList() {
head = nullptr;
tail = nullptr;
size = 0;
}

void insertFront(T val);


void insertBack(T val);
void insertAt(T val, int index);

void deleteFront();
void deleteBack();
void deleteAt(int index);

void printList();
int getSize();

private:
Node<T>* head;
Node<T>* tail;
int size;
};

```

## Insertion
![[Pasted image 20230319143258.png]]

To insert an element in a double-linked list, we must create a new node and update
the pointers of the adjacent nodes. Here are three methods for inserting an element
into a double-linked list:

```cpp
template<typename T>
void DoubleLinkedList<T>::insertFront(T val) {
Node<T>* newNode = new Node<T>(val);

if (head == nullptr) {
head = newNode;
tail = newNode;
}
else {
newNode->next = head;
head->prev = newNode;
head = newNode;
}

size++;
}

template<typename T>
void DoubleLinkedList<T>::insertBack(T val) {
Node<T>* newNode = new Node<T>(val);

if (tail == nullptr) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
newNode->prev = tail;
tail = newNode;
}

size++;
}

template<typename T>
void DoubleLinkedList<T>::insertAt(T val, int index) {
if (index < 0 || index > size) {
cout << "Invalid index" << endl;
return;
}

if (index == 0) {
insertFront(val);
return;
}

if (index == size) {
insertBack(val);
return;
}

Node<T>* current = head;


for (int i = 0; i < index - 1; i++) {
current = current->next;
}

Node<T>* newNode = new Node<T>(val);


newNode->prev = current;
newNode->next = current->next;
current->next->prev = newNode;
current->next = newNode;

size++;
}
```

### Deletion

To delete an element in a double-linked list, we must update the pointers of the


adjacent nodes and delete the node. Here are three methods for deleting an element
from a double-linked list:

```cpp
template<typename T>
void DoubleLinkedList<T>::deleteFront() {
if (head == nullptr) {
cout << "List is empty" << endl;
return;

```

---
# Implementation
```cpp
#include <iostream>

template<typename T>
class List {
public:
List() {
size = 0;
head = nullptr;
tail = nullptr;
}
~List() {
clear();
}

int GetSize() const {


return size;
}

bool IsEmpty() const {


return (size == 0);
}

void PushFront(T data);


void PushBack(T data);
void InsertAt(T data, int index);
void RemoveAt(int index);
void PopFront();
void PopBack();
void Clear();

T& operator[](const int index) const {


if (index < 0 || index >= size) {
throw std::out_of_range("Index out of range");
}

Node<T>* current = head;


int i = 0;
while (current != nullptr && i < index) {
current = current->next;
i++;
}

return current->data;
}

private:
template<typename T>
class Node {
public:
Node(T data = T(), Node* prev = nullptr, Node* next = nullptr) {
this->data = data;
this->prev = prev;
this->next = next;
}

T data;
Node* prev;
Node* next;
};

int size;
Node<T>* head;
Node<T>* tail;
};

template<typename T>
void List<T>::PushFront(T data) {
if (IsEmpty()) {
head = tail = new Node<T>(data);
}
else {
Node<T>* newHead = new Node<T>(data, nullptr, head);
head->prev = newHead;
head = newHead;
}
size++;
}

template<typename T>
void List<T>::PushBack(T data) {
if (IsEmpty()) {
head = tail = new Node<T>(data);
}
else {
Node<T>* newTail = new Node<T>(data, tail, nullptr);
tail->next = newTail;
tail = newTail;
}
size++;
}

template<typename T>
void List<T>::InsertAt(T data, int index) {
if (index < 0 || index > size) {
throw std::out_of_range("Index out of range");
}

if (index == 0) {
PushFront(data);
return;
}
if (index == size) {
PushBack(data);
return;
}

Node<T>* current = head;


for (int i = 0; i < index; i++) {
current = current->next;
}

Node<T>* newNode = new Node<T>(data, current->prev, current);


current->prev->next = newNode;
current->prev = newNode;
size++;
}

template<typename T>
void List<T>::RemoveAt(int index) {
if (index < 0 || index >= size) {
throw std::out_of_range("Index out of range");
}

if (index == 0) {
PopFront();
return;
}
if (index == size - 1) {
PopBack();
return;
}

Node<T>* current = head;


for (int i = 0; i < index; i++) {
current = current->next;
}

current->prev->next = current->next;
current->next->prev = current->prev;
delete current;
size--;

```

You might also like