#include <iostream>
using namespace std;
/*
________
| Data |
|________|
| *next |
|________|
*/
struct Data
{
int data;
Data *next;
Data(int); // Data(int val)
~Data();
void print();
};
// konstruktor
Data :: Data(int val)
{
data = val;
next = NULL;
// Ponizej jest rysunek jak wyglada lista
// - element i wskaznik na kolejny element
// - na koncu wskaznik na pusty element
}
Data :: ~Data()
{
cout << "Deleted ";
print();
cout << endl;
}
void Data :: print()
{
cout << " (" << data << ") ";
}
/*
________ ________ ________ ________ ________
| Data | ->| Data | ->| Data | | Data | ->| NULL |
List: |________| / |________| / |________| ... |________| / |________|
| *next |/ | *next |/ | *next | | *next |/ | |
|________| |________| |________| |________| |________|
first ->next ->next ... ->next ->next
^
|
first->next->next
*/
struct List
{
// pierwszy element listy
Data *first;
List();
List(int); // List(int val)
~List();
void push(int); // push(int val)
int pop();
void replace(int, int); // replace(int pos, int val)
void insert(int, int); // insert(int pos, int val);
void erase(int); // erase(int pos);
void print();
int size();
void sort();
};
// konstruktor tworzy pierwszy blok jako pusty
List :: List()
{
cout << "New empty list" << endl;
first = NULL;
}
// konstruktor tworzy pierwszy element
// kontruktor elementu tworzy wskaznik na kolejny pusty blok
List :: List(int val)
{
cout << "New initialised list" << endl;
first = new Data(val);
}
// destruktor usuwa wszystkie elementy z listy
List :: ~List()
{
cout << "List has been deleted" << endl;
Data *temp = first;
// Windows:
Data *next = first->next;
// chodzimy po liscie
// Linux:
// while (temp)
// Windows:
while (temp->next)
{
// usuwamy obecny
delete temp;
// temp wskazuje na nastepny
// Linux:
// temp = temp->next;
// Windows:
temp = next;
next = next->next;
}
// pozostanie nam ostatni element do usuniecia
delete temp;
}
// wstawiamy nowy element na koncu listy,
// pusty blok staje sie nowym elementem
void List :: push(int val)
{
cout << "Pushed data into list (" << val << ")" << endl;
// tworzy nowy element
Data *data = new Data(val);
if (first == NULL)
{
/*
Gdy lista nie zawiera elementow
________
| NULL |
List: |________|
| |
|________|
push(val)
Wstawiamy elment jako pierwszy
________ ________
| Data | ->| NULL |
List: |__(val)_| / |________|
| *next |/ | |
|________| |________|
*/
first = data;
}
else
{
/*
Gdy lista zawiera elementy, obchodzimy ja do konca i tam
wstawiamy nowy element
________ ________ ________
| Data | ->| Data | ->| NULL |
List: |________| / |________| / |________|
| *next |/ | *next |/ | |
|________| |________| |________|
push(val)
Wstawiamy element na koniec
________ ________ ________ ________
| Data | ->| Data | ->| Data | ->| NULL |
List: |________| / |________| / |__(val)_| / |________|
| *next |/ | *next |/ | *next |/ | |
|________| |________| |________| |________|
*/
// zaczynamy od pierwszego elementu
Data *temp = first;
// chodzimy po liscie tak dlugo, az aktualny element
// nie wskazuje na pusty blok
while (temp->next)
{
temp = temp->next;
}
// jak znajdzie taki blok to go uzupelnia
temp->next = data;
temp->next->next = NULL;
}
}
// Sciaga ostatni element z listy zastepujac go pustym blokiem
int List :: pop()
{
/*
________ ________ ________ ________
| Data | ->| Data | ->| Data | ->| NULL |
List: |________| / |________| / |__(val)_| / |________|
| *next |/ | *next |/ | *next |/ | |
|________| |________| |________| |________|
pop()
Sciagamy ostatni
________ ________ ________
| Data | ->| Data | ->| NULL |
List: |________| / |________| / |________|
| *next |/ | *next |/ | |
|________| |________| |________|
*/
int ret_val;
if (first == NULL)
{
// Jezeli lista pusta to error
cout << "Empty list! Cannot pop." << endl;
ret_val = 0;
}
else if (!first->next)
{
// Jezeli lista 1-elementowa to usuwamy i zerujemy
ret_val = first->data;
delete first->next;
first = NULL;
}
else
{
// Jezeli lista >1-elementowa
// poprzednik ostatniego
Data *prev = first;
// ostatni
Data *data = first->next;
// chodzimy po liscie tak dlugo, az ostatni element
// nie wskazuje na pusty blok
while (data->next)
{
prev = prev->next;
data = data->next;
}
// zwracamy dane z ostatniego
ret_val = data->data;
// usuwamy ostatni
delete data;
// poprzednik wskazuje na pusty blok
prev->next = NULL;
}
cout << "Popped data from list (" << ret_val << ")" << endl;
return ret_val;
}
void List :: replace(int pos, int val)
{
if (pos < 1 or pos > size())
{
cout << "Index out of range!" << endl;
return;
}
else
{
cout << "Data at pos " << pos << " has been replaced by " << val << endl;
int i = 1;
Data *temp = first;
while (i != pos)
{
i++;
temp = temp->next;
}
temp->data = val;
}
}
void List :: insert(int pos, int val)
{
// nowy element
Data *data = new Data(val);
if (pos < 1)
{
cout << "Index out of range!" << endl;
return;
}
else if(!first)
{
cout << "Inserted " << val << " at pos " << pos << endl;
// gdy lista pusta wstawiamy nowy element jako pierwszy
first = data;
}
else
{
cout << "Inserted " << val << " at pos " << pos << endl;
int i = 1;
if (!first)
{
// Jezeli lista pusta
first = data;
}
else
{
// Jezeli lista zawiera elementy
// poprzednik
Data *prev = first;
// nastepnik
Data *next = first->next;
if (pos == 1)
{
first = data;
data->next = prev;
}
else
{
while (i != pos)
{
i++;
prev = prev->next;
next = next->next;
}
// poprzednik wskazuje na nowy element
prev->next = data;
// nowy element wskazuje na nastepnik;
data->next = next;
}
}
}
}
void List :: erase(int pos)
{
if (pos < 1 or pos > size())
{
cout << "Index out of range!" << endl;
return;
}
else
{
cout << "Erased data from pos " << pos << endl;
int i = 1;
Data *temp = first;
if (pos == 1)
{
// Jezeli usuwamy pierwszy element
delete first;
// pierwszy staje sie nastepnym
first = temp->next;
}
else
{
// chodzimy po liscie
while (temp)
{
if ((i + 1) == pos)
{
// Jezeli kolejny ma byc usuniety
// zapisujemy sobie kolejny po usuwanym
Data *temp2 = temp->next->next;
// usuwamy
delete temp->next;
// obecny wskazuje na kolejny po usuwanym
temp->next = temp2;
break;
}
temp = temp->next;
i++;
}
}
}
}
void List :: print()
{
cout << "HEAD";
Data *temp = first;
while (temp)
{
cout << "->";
temp->print();
temp = temp->next;
}
cout << endl;
}
int List :: size()
{
int size = 0;
Data *temp = first;
while (temp)
{
size++;
temp = temp->next;
}
return size;
}
void List :: sort()
{
if (!first or !first->next)
{
return;
}
else
{
Data *prev = first;
for (int i = 0; i < size(); i++)
{
Data *next = prev->next;
int temp;
for (int j = i; j < size() - 1; j++)
{
if (prev->data > next->data)
{
temp = prev->data;
prev->data = next->data;
next->data = temp;
}
next = next->next;
}
prev = prev->next;
}
}
}
int main()
{
List *lista = new List();
lista->print();
lista->insert(1, -5);
lista->print();
lista->push(-1);
lista->push(2);
lista->push(-2);
lista->print();
lista->sort();
lista->print();
lista->pop();
lista->print();
lista->replace(0, 4);
lista->replace(1, 4);
lista->print();
lista->insert(1, 6);
lista->print();
lista->erase(6);
lista->erase(3);
lista->print();
delete lista;
return 0;
}