#ifndef LTDL
#define LTDL
template struct DNode{
T data;
DNode *next, *prev;
DNode(){ next = NULL; prev = NULL; }
};
template class DList{
private:
DNode* head, * tail;
unsigned long long capacity;
bool destroy;
public:
DList(){ head = NULL; tail = NULL; capacity = 0; destroy = true; }
unsigned long long get_capacity(){ return capacity; }
void set_destroy(bool d){ destroy = d; }
void reset(){ capacity = 0; head = NULL; tail = NULL; }
DNode* find_node(unsigned long long i){
if (capacity == 0) return NULL;
else if (i == 0) return this->head;
else if (i == (capacity - 1)) return this->tail;
else if ((i >= 0) && (i < capacity)){
DNode* curr = head;
for (unsigned long long c = 0; c < i; c++){
curr = curr->next;
}
return curr;
}
else return NULL;
}
DNode* grab_node(unsigned long long i){
if ((i >= 0) && (i < capacity)){
DNode* curr = find_node(i);
if (curr != NULL){
if (curr->next != NULL) curr->next->prev = curr->prev;
if (curr->prev != NULL) curr->prev->next = curr->next;
if (curr == head) head = curr->next;
if (curr == tail) tail = curr->prev;
capacity--;
return curr;
}
}
else return NULL;
}
bool remove_node(DNode* node){
DNode* curr = head;
while (curr != NULL){
if (curr == node){
break;
}
curr = curr->next;
}
if (curr != NULL){
if (curr->prev != NULL) curr->prev->next = curr->next;
if (curr->next != NULL) curr->next->prev = curr->prev;
return false;
}
else return true;
}
bool delete_node(unsigned long long i){
DNode* tmp = grab_node(i);
if (tmp != NULL){
capacity--;
delete tmp;
return false;
}
else return true;
}
bool eliminate_node(DNode* node){
if (remove_node(node) == false){
delete node;
return false;
}
else return true;
}
void clear(){
DNode* curr = head;
DNode* curr_n = NULL;
if (curr != NULL) curr_n = curr->next;
while (curr != NULL){
delete curr;
curr = curr_n;
if (curr != NULL) curr_n = curr->next;
}
reset();
}
bool prepend_node(DNode* node){
if (node != NULL){
if (head != NULL){
head->prev = node;
}
node->next = head;
head = node;
head->prev = NULL;
capacity++;
return false;
}
else return true;
}
bool append_node(DNode* node){
if (node != NULL){
if (tail != NULL){ tail->next = node; }
if (head == NULL){ head = node; }
else { node->prev = tail; }
tail = node;
capacity++;
return false;
}
else return true;
}
bool insert_before(unsigned long long i, DNode* node){
if ((i >= 0) && ((i < capacity) || (capacity == 0))){
if (head == NULL){
head = node;
head->prev = NULL;
head->next = NULL;
tail = node;
capacity++;
return false;
}
else {
DNode* curr = find_node(i);
if (curr != NULL){
if (curr == head){
node->prev = NULL;
node->next = head;
head->prev = node;
head = node;
capacity++;
return false;
}
else {
node->next = curr;
node->prev = curr->prev;
if (curr->prev != NULL) curr->prev->next = node;
curr->prev = node;
capacity++;
return false;
}
}
}
}
return true;
}
bool insert_before(DNode* dest, DNode* src){ }
bool insert_after(unsigned long long i, DNode* node){
if ( (i >= 0) && ((i < capacity) || (capacity == 0)) ){
if (head == NULL){
node->prev = NULL;
node->next = NULL;
head = node;
tail = node;
capacity++;
return false;
}
else {
DNode* curr = find_node(i);
if (curr != NULL){
if (curr == tail){
node->prev = tail;
node->next = NULL;
tail->next = node;
tail = node;
capacity++;
return false;
}
else {
node->prev = curr;
node->next = curr->next;
if (curr->next != NULL) curr->next->prev = node;
curr->next = node;
capacity++;
return false;
}
}
}
}
else return true;
}
bool insert_after(DNode* dest, DNode* src){ }
bool swap_nodes(DNode* node1, DNode* node2){
if (((node1 != NULL)&&(node2 != NULL)) && (node1 != node2)){
DNode tmp;
if (node1->next == node2){
tmp.prev = node1->prev;
tmp.next = node1->next;
node1->next = node2->next;
if (node2->next != NULL) node2->next->prev = node1;
else tail = node1;
node2->next = node1;
node2->prev = node1->prev;
if (node1->prev != NULL) node1->prev->next = node2;
else head = node2;
node1->prev = node2;
return false;
}
else if (node2->next == node1){
tmp.prev = node2->prev;
tmp.next = node2->next;
node2->next = node1->next;
if (node1->next != NULL) node1->next->prev = node2;
else tail = node2;
node1->next = node2;
node1->prev = node2->prev;
if (node2->prev != NULL) node2->prev->next = node2;
else head = node1;
node2->prev = node1;
return false;
}
else{
tmp.prev = node1->prev;
tmp.next = node1->next;
node1->next = node2->next;
node1->prev = node2->prev;
if (node1->next != NULL) node1->next->prev = node1;
if (node1->prev != NULL) node1->prev->next = node1;
node2->next = tmp.next;
node2->prev = tmp.prev;
if (node2->next != NULL) node2->next->prev = node2;
if (node2->prev != NULL) node2->prev->next = node2;
if (head == node1) head = node2;
else if (head == node2) head = node1;
if (tail == node1) tail = node2;
else if (tail == node2) tail = node1;
return false;
}
}
return true;
}
bool swap_nodes(unsigned long long a, unsigned long long b){
if ((a!=b) && ((a>=0)&&(a=0)&&(b* A = find_node(a);
DNode* B = find_node(b);
return swap_nodes(A, B);
}
else return true;
}
void sort(){
DNode* lowest = NULL;
DNode* curr = NULL;
DNode* new_head = NULL;
DNode* new_tail = NULL;
unsigned long long tmp_cap = capacity;
while (tmp_cap > 0){
curr = head;
lowest = head;
while (curr != NULL){
if (curr->data < lowest->data){
lowest = curr;
}
curr = curr->next;
}
if (lowest->prev != NULL){
lowest->prev->next = lowest->next;
}
else {
head = lowest->next;
}
if (lowest->next != NULL){
lowest->next->prev = lowest->prev;
}
else {
tail = lowest->prev;
}
tmp_cap--;
if (new_head == NULL){
new_head = lowest;
new_head->prev = NULL;
new_head->next = NULL;
new_tail = new_head;
}
else {
if (new_head->next == NULL){
new_head->next = lowest;
lowest->prev = new_head;
new_tail = lowest;
}
else {
new_tail->next = lowest;
lowest->prev = new_tail;
new_tail = lowest;
}
}
}
head = new_head;
tail = new_tail;
}
void append_list(DList &other){
DNode* other_head = other.find_node(0);
DNode* other_tail = other.find_node(other.get_capacity - 1);
other_head->prev = tail;
tail->next = other_head;
tail = other_tail;
other.reset();
}
~DList(){ if (destroy == true) clear(); }
};
===d_main.cpp===
#include
#include "ltdl.hpp"
int main(){
DList dlist;
char option = 'Q';
bool running = true;
std::cout << " *** Linked Lists Demo Programme ***"
<< std::endl;
while (running == true){
std::cout << std::endl;
std::cout << " *** Options ***" << std::endl;
std::cout << "(B) - Build List" << std::endl;
std::cout << "(P) - Print List" << std::endl;
std::cout << "(D) - Print Detailed List" << std::endl;
std::cout << "(I) - Insert New Node Before" << std::endl;
std::cout << "(i) - Insert New Node After" << std::endl;
std::cout << "(p) - Prepend New Node" << std::endl;
std::cout << "(A) - Append New Node" << std::endl;
std::cout << "(V) - View Node" << std::endl;
std::cout << "(R) - Remove Node" << std::endl;
std::cout << "(G) - Grab Node" << std::endl;
std::cout << "(d) - Delete Node" << std::endl;
std::cout << "(S) - Swap Nodes" << std::endl;
std::cout << "(s) - Sort List (Ascending)" << std::endl;
std::cout << "(C) - Clear List" << std::endl;
std::cout << "(Q) - Quit Demo Programme" << std::endl;
std::cout << std::endl << "Choice: ";
std::cin >> option;
if (option == 'P'){
std::cout << std::endl;
DNode* curr = dlist.find_node(0);
unsigned long long c = 0;
std::cout << "NULL ";
while (curr != NULL){
std::cout << "<-> (" << c << "[" << curr->data << "]) ";
curr = curr->next;
if (curr == NULL) std::cout << "<-> NULL";
c++;
}
std::cout << std::endl;
}
else if (option == 'D'){
std::cout << std::endl;
DNode* curr = dlist.find_node(0);
unsigned long long c = 0;
std::cout << " list.capacity: " << dlist.get_capacity() << std::endl;
std::cout << " list.head: " << dlist.find_node(0) << std::endl;
while (curr != NULL){
std::cout << "Node[" << c << "]->value: " << curr->data << std::endl;
std::cout << "Node[" << c << "] : " << curr << std::endl;
std::cout << "Node[" << c << "]->prev : " << curr->prev << std::endl;
std::cout << "Node[" << c << "]->next : " << curr->next << std::endl;
if (curr->next == NULL){
std::cout << " list.tail: " << curr <next;
c++;
}
std::cout << std::endl;
}
else if (option == 'V'){
unsigned long long i = 0;
std::cout << "Node to view: ";
std::cin >> i;
DNode* tmp = dlist.find_node(i);
std::cout << "Node: " << tmp << std::endl;
if (tmp != NULL){
std::cout << "Node value: " << tmp->data << std::endl;
std::cout << "Node->next: " << tmp->next << std::endl;
std::cout << "Node->prev: " << tmp->prev << std::endl;
}
}
else if (option == 'B'){
unsigned long long c = 0;
bool build = true;
char cont = 'y';
while (build == true){
std::cout << "Node[" << c << "] value? : ";
DNode* tmp = new DNode;
std::cin >> tmp->data;
dlist.append_node(tmp);
std::cout << "Add more nodes? y/n: ";
std::cin >> cont;
if (cont != 'y') build = false;
c++;
}
}
else if (option == 'A'){
DNode* tmp = new DNode;
std::cout << "New node value: ";
std::cin >> tmp->data;
dlist.append_node(tmp);
}
else if (option == 'p'){
DNode* tmp = new DNode;
std::cout << "New node value: ";
std::cin >> tmp->data;
dlist.prepend_node(tmp);
}
else if (option == 'C'){
dlist.clear();
}
else if (option == 'Q'){
std::cout << "Demo programme is exiting. Good-bye." << std::endl;
return false;
}
else if (option == 's'){
dlist.sort();
}
else if (option == 'd'){
unsigned long long i = 0;
std::cout << "Node to delete: ";
std::cin >> i;
dlist.delete_node(i);
}
else if (option == 'G'){
unsigned long long i = 0;
std::cout << "Node to grab: ";
std::cin >> i;
DNode* tmp = dlist.grab_node(i);
std::cout << "Grabbed node : " << tmp << std::endl;
if (tmp != NULL){
std::cout << "Grabbed node value: " << tmp->data << std::endl;
std::cout << "Grabbed node->next: " << tmp->next << std::endl;
std::cout << "Grabbed node->prev: " << tmp->prev << std::endl;
std::cout << "Deleting grabbed node..." << std::endl << std::endl;
delete tmp;
}
}
else if (option == 'I'){
DNode* tmp = new DNode;
unsigned long long i = 0;
std::cout << "Node to insert before: ";
std::cin >> i;
std::cout << "Value of new node: " << std::endl;
std::cin >> tmp->data;
bool fail = dlist.insert_before(i, tmp);
if (fail == true){
std::cout << "Sorry. Cannot insert before the specified node."
<< std::endl;
}
}
else if (option == 'i'){
DNode* tmp = new DNode;
unsigned long long i = 0;
std::cout << "Node to insert after: ";
std::cin >> i;
std::cout << "Value of new node: ";
std::cin >> tmp->data;
bool fail = dlist.insert_after(i, tmp);
if (fail == true){
std::cout << "Sorry. Cannot insert after the specified node."
<< std::endl;
}
}
else if (option == 'S'){
bool fail = false;
unsigned long long a = 0;
unsigned long long b = 0;
std::cout << "Node 1: ";
std::cin >> a;
std::cout << "Node 2: ";
std::cin >> b;
if ((a>=0)&&(a=0)&&(b* A = dlist.find_node(a);
DNode* B = dlist.find_node(b);
fail = dlist.swap_nodes(A, B);
} else fail = true;
if (fail == true){
std::cout << "Sorry. There was an error swapping the specified nodes."
<< " The results may not be what you expected." << std::endl;
}
}
}
return false;
}