Myślałem że wstawianie na koniec to operacja liniowa tzn że musimy przejść wskaźnikami całą listę aby dodać na koniec
co mogłoby zwiększyć złożoność a wskaźnik tail występuje tylko w dwukierunkowych
Ile pamięci możemy zaoszczędzić pozbywając się wartowników
Oto kod który powinien się skompilować
#include <iostream>
#include <cstdlib>
using namespace std;
template <class T>
class Node
{
private:
T data;
Node<T> *next;
public:
Node<T>(){next=NULL;}
Node<T> (T dane) { data = dane; next = NULL; }
T Data () { return data; }
Node<T> * Next () { return next; }
void changeNext (Node<T> *n) { next = n; }
};
template <class T>
class List
{
private:
Node<T> *L;
public:
List () { L = NULL; }
~List () { removeallNode (); }
bool emptyList (); // zwraca 1, jesli lista jest pusta
void addNode (Node<T> *n); //dodaje wierzcho�ek n na pocz�tek listy
void printNode (); //drukuje list�
void removeNode (Node<T> *n); //usuwa wierzcho�ek
void removeallNode (); //usuwa ca�� list�
Node<T> *locateNode (T i); //zwraca wska�nik do wierzcho�ka zawieraj�cego warto�� i
void split(List<T> & , List<T> & );
void merge(List<T> & , List<T> & );
void merge_sort();
};
template<class T>
bool List<T>::emptyList (){ // zwraca 1, jesli lista jest pusta
if (L == NULL) return 1;
else return 0;
}
template<class T>
void List<T>::addNode (Node<T> *n){ //dodaje wierzcho�ek n na pocz�tek listy
n -> changeNext (L);
L = n;
}
template<class T>
void List<T>::printNode (){ //drukuje list�
Node<T> *q;
q = L;
while (q != NULL)
{
cout << q -> Data() << endl;
q = q -> Next();
}
}
template<class T>
void List<T>::removeNode (Node<T> *n){ //usuwa wierzcho�ek
if (L == n)
{
L = L -> Next();
delete n;
}
else {
Node<T> *q;
q = L;
while ((q -> Next() != NULL) && (q -> Next() != n)) q = q -> Next();
if (q -> Next() == n)
{
q -> changeNext (q -> Next() -> Next());
delete n;
}
}
}
template<class T>
void List<T>::removeallNode (){ //usuwa ca�� list�
Node<T> *q;
while (L != NULL)
{
q = L;
L = L -> Next ();
delete q;
}
}
template<class T>
Node<T> *List<T>::locateNode (T i){ //zwraca wska�nik do wierzcho�ka zawieraj�cego warto�� i
Node<T> *q;
q = L;
while ((q != NULL) && (q -> Data() != i)) q = q -> Next ();
return q;
}
template<class T>
void List<T>::split(List<T> & l1, List<T> & l2)
{
Node<T> * p1, * p2;
bool s = false;
l1.addNode(new Node<T>());
l2.addNode(new Node<T>());
p1 = l1.L;
p2 = l2.L;
while(L)
{
if(s)
{
p2->changeNext(L) ;
p2 = p2->Next();
}
else
{
p1->changeNext(L);
p1 = p1->Next();
}
L = L->Next();
s = !s;
}
p1->changeNext(NULL);
p2->changeNext(NULL);
l1.removeNode(l1.L);
l2.removeNode(l2.L);
}
template<class T>
void List<T>::merge(List<T> & l1, List<T> & l2)
{
Node<T> * p;
Node<T> * q=new Node<T>();
addNode(q);
p = L;
while(l1.L && l2.L)
{
if(l1.L->Data() > l2.L->Data())
{
p->changeNext(l2.L);
l2.L = l2.L->Next();
}
else
{
p->changeNext(l1.L);
l1.L = l1.L->Next();
}
p = p->Next();
}
while(l1.L)
{
p->changeNext(l1.L);
l1.L = l1.L->Next();
p = p->Next();
}
while(l2.L)
{
p->changeNext(l2.L);
l2.L = l2.L->Next();
p = p->Next();
}
removeNode(L);
}
template<class T>
void List<T>::merge_sort()
{
List<T> h1,h2;
if(L && L->Next())
{
split(h1,h2);
h1.merge_sort();
h2.merge_sort();
merge(h1,h2);
}
}
/*void List::split(List & l1, List & l2)
{
Node* fast;
Node* slow;
if(L==NULL||L->Next()==NULL)
{
l1.L=L;
l2.L=NULL;
}
else
{
slow=L;
fast=L->Next();
}
while(fast!=NULL)
{
fast=fast->Next();
if(fast!=NULL)
{
slow=slow->Next();
fast=fast->Next();
}
}
l1.L=L;
l2.L=slow->Next();
slow->changeNext(NULL);
}*/
int main ()
{
int wybor, liczba;
List<int> lista;
do
{
cout << "****************************\n";
cout << "* Lista pojedynczo wiazana *\n";
cout << "****************************\n";
cout << "\n\n1 - dodawanie liczby do listy\n";
cout << "2 - drukowanie listy\n";
cout << "3 - usuwanie liczby z listy\n";
cout << "4 - usuwanie wszystkich liczb\n";
cout << "5 - szukanie liczby\n";
cout << "6 - sortowanie listy\n";
cout << "0 - wyjscie z programu\n";
cout << "Twoj wybor?\t";
cin >> wybor;
switch (wybor)
{
case 1: cout << "\n\nPodaj liczbe:\t";
cin >> liczba;
Node<int> *q;
q = new Node<int> (liczba);
lista.addNode(q);
break;
case 2: if (!lista.emptyList())
{
cout << "\n\nNa liscie sa:\n";
lista.printNode();
}
else cout << "\n\nLista pusta\n";
system ("PAUSE");
break;
case 3: cout << "\n\nPodaj liczbe:\t";
cin >> liczba;
Node<int> *r;
r = lista.locateNode(liczba);
if (r) lista.removeNode(r);
else cout << "\n\nNie ma takiej liczby na liscie\n";
system ("PAUSE");
break;
case 4: lista.removeallNode();
break;
case 5: cout << "\n\nPodaj liczbe:\t";
cin >> liczba;
Node<int> *s;
s = lista.locateNode(liczba);
if (s) cout << "Liczba jest na liscie\n";
else cout << "Liczby nie ma na liscie\n";
system ("PAUSE");
break;
case 6: lista.merge_sort();
system("PAUSE");
break;
}
system ("CLS");
}
while (wybor != 0);
return 0;
}
Funkcja w której próbowałem pozbyć się wartowników jest zakomentowana