#include <iostream>

using namespace std;

class Stos
{
	public:
		class Element
		{
			private:
				char * n;
				Element * next;
			public:
				Element * nextGet() const { return next;}
				char * getN() const {return n;}
				void nextSet(Element * a) { next = a; }
//				Element & operator=(const Element & a);
				Element & operator=(char *);
				Element(): n(NULL), next(0) {};
				Element (const Element & a);
				friend ostream &operator<<(ostream &s,const Stos::Element &a);
//				Element & operator=(const Element &a);
				unsigned size(void) {return strlen(n);}
		};
		Stos(): rozmiar(0), poczatek(NULL) {}
		~Stos();
		Stos &operator<<(char * a) { add(a); return(*this); }
		Stos &operator<<(Element & a) { add(a); return(*this); }
//		Stos &operator>>(Element & a) { rem(a); return(*this); }
		friend ostream &operator<<(ostream &s,const Stos &S);
		Element remove(unsigned i);
		Element * last() const;
		Element * elementPtr (unsigned i) const;
		unsigned operator()() const { return rozmiar; }
		void Sort();
		Element * getPoczatek() { return poczatek;}
	private:
		unsigned najdluzszy(void);
		unsigned rozmiar;
		Element * poczatek;
		void rem (Element &a);
		void add (const Element &a);
		void add (char *);
		void move(Stos & B);
		
};
void Stos::move (Stos & B)
{
     		last()->nextSet(B);
     		
}
/*
Stos::Element & Stos::Element::operator=(const Element & a)
{
	if()
	v = a.v;
	next = a.next;
	return(*this);
}
*/
void Stos::add(const Element & a)
{
	Element * N = new Element;
	(*N) = a;
	N->nextSet(NULL);
	if (rozmiar == 0)
	{
		poczatek = N;
	} else {
		Element * b = last();
		b->nextSet(N);
	}
	rozmiar++;
	return;
}

unsigned Stos::najdluzszy(void)
{
	unsigned naj = 0;
	if (rozmiar == 0) return 0;
	Stos::Element * p = poczatek;
	while(true)
	{
		if (p == NULL) break;
		unsigned rozm = strlen(p->getN());
		if (rozm > naj) naj = rozm;
		p = p->nextGet();
	}
	return naj;

}

void Stos::Sort (void)
{
	Stos stosy[256];
//	cout << "AAA(" << najdluzszy() << ")" << endl;
	unsigned curr = najdluzszy() - 1;
	Stos::Element * p = poczatek;
	unsigned naj = 0;
	while(true)
	{
		if (p == NULL) break;
		if (curr >= p->size())
		{
			stosy[0].add(p->getN());
		} else {       	
		       	stosy[p->getN()[curr]].add(p->getN());
		}
		Element * t = p;
		poczatek = p;
		delete t;
		unsigned rozm = strlen(p->getN());
		if (rozm > naj) naj = rozm;
		p = p->nextGet();
	}
	
/*
	cout << stosy[0];
	for (unsigned i='a'; i<'d'; ++i)
	{
	    	      cout << stosy[i];
        }
*/		      
}

ostream &operator<<(ostream &s,const Stos::Element &a)
{
	return(s << a.n);
}

ostream &operator<<(ostream &s,const Stos &S)
{
	s<< "Stos:" << endl;
	Stos::Element *i=S.poczatek;
	if(i)
	{
		while(true)
		{
			s << "  " << (*i) << endl;
			i=i->nextGet();
			if(!i)break;
		}
	}
	return(s);
}

Stos::~Stos()
{
	if (rozmiar == 0) return;
	return;
	while (poczatek)
	{
		Element *t = poczatek->nextGet();
		delete poczatek;
		poczatek = t;
	}
}

Stos::Element * Stos::elementPtr (unsigned i) const
{
	Stos::Element * p = poczatek;
	for (unsigned c = 0; c != i; c++)
	{
		p = p->nextGet();
	}
	return p;
}

Stos::Element * Stos::last() const
{
	if (!rozmiar)
	{
		return(NULL);
	} else {
		return elementPtr(operator()() - 1);
	}
}

Stos::Element & Stos::Element::operator=(char * napis)
{
//	cout << "Element:dodajemy(" << napis << ')' << endl;
	if (n) delete[] n;
	unsigned size=strlen(napis)+1;
	n = new char[size];
	memcpy(n, napis, size);
	return(*this);
}

void Stos::add(char * a)
{
//	cout << "Dodajemy(" << a << ')' << endl;
	Element * N = new Element;
	(*N) = a;
	N->nextSet(NULL);
	if (rozmiar == 0)
	{
		poczatek = N;
	} else {
		Element * b = last();
		b->nextSet(N);
	}
	rozmiar++;
	return;
}

int main(void)
{
	while(true)
	{
		Stos S;
		unsigned Cnt = 0;
		while (true)
		{
			char Bufor[256];
			cout << "Podaj napis nr" << (++Cnt) << ": ";
			cin.getline(Bufor, 256, '\n');
			if (!*Bufor) { break; }
			S << Bufor;
		}
		cout << S << endl;
		S.Sort();
		/*
		cout << S << endl;
		if (!S) break;
		*/
	}
	return 0;
	cin.get();
}

