» »

[C++]Kopirni konstruktor, Dvosmerni seznam, samo me zanima če prav razmišljam

[C++]Kopirni konstruktor, Dvosmerni seznam, samo me zanima če prav razmišljam

Moravče ::

Evo, to je kar sem napisal, pa ne vem če je prav, če prav razmišljam, glejte komentarje:

//-------------------------------
template <class T>
class a2seznam
{
protected:

	struct Element
	{
		Element * k_nasl;
		Element * k_prej;
		T podatek;
		int index;
	};

	Element * k_zacetek;
	Element * k_konec;

public:
	a2seznam();
	a2seznam(const a2seznam&);
	~a2seznam();
//----------------------------------------
template <class T> //kopirni konstruktor
a2seznam<T>::a2seznam(const a2seznam& a)
{	
	Element * k_novi;
	Element * k_trenutniA;
	k_trenutniA = a.k_zacetek;

	k_zacetek = NULL;
	k_konec = NULL;

	if (k_trenutniA == NULL){
		cout << "Seznam iz katerega hocemo kopirati je prazen \n";
		return;
	}
	while(k_trenutniA != a.k_konec)
	{
		k_novi = new Element();
		k_novi->index = k_trenutniA ->index;
		k_novi->podatek = k_trenutniA ->podatek;
                
                //kar je tukaj naprej nisem čisto ziher
		if(k_zacetek == NULL) 
/* se pravi, če v novem seznamu še ni nobenega elementa, naredim novega in povežem tak
O bom uporabil za element, -> kaže (tako si ta znak predstavljam) pa mi malo probleme dela, za = pa nisem čisto ziher kaj pomeni tukaj pri kazalcih (lahko malo razlage, če je prav uporabljen...)
k_zac->0*/
		{
			k_zacetek = k_novi;
//k_zac->0->k_konec
			k_novi->k_nasl = k_konec;
//     <-
//k_zac->0->k_konec
			k_novi->k_prej = k_zacetek;
			k_konec = k_novi; 
/*??? je to prav??? ali bi moralo biti k_konec->k_prej = k_novi, namreč ne vem tudi kako je z k k_konec, je to Element, le da nima podatkov - T in index; S tem bi rad dobil tole
//_____ <- __ <- _________    (to navrh kažeta v nasprotno smer)
//k_zac|->|0 |-> |k_konec|
 
V naprej podobni problemi...*/
			k_konec->k_nasl = NULL;
		}
		else
		{
			k_konec->k_nasl = k_novi;
			k_novi->k_prej = k_konec;
			k_konec = k_konec->k_nasl;
			k_novi->k_nasl = k_konec;
			k_konec->k_nasl = NULL;
		}
		k_trenutniA = k_trenutniA->k_nasl;
	}           
	
	
}


No, upam da razumete kaj me muči :)

Lep pozdrav in hvala za pomoč :)

Rapsey ::

Else mas ful cudno napisan.
k_konec->k_nasl = k_novi; // ok naslednji je nov
k_novi->k_prej = k_konec;
k_konec = k_konec->k_nasl; // postavis se en korak naprej k_konec = k_novi
k_novi->k_nasl = k_konec; // huh??? naredil cikel. naslednji od nov je nov.
k_konec->k_nasl = NULL; // zdaj pa popravis in ni vec cikla.
Dealing with failure is easy: Work hard to improve.
Success is also easy to handle: You've solved the wrong problem.
Work hard to improve. - Alan J. Perlis

Gundolf ::

Glede kazalcev, takole je (upam da razlagam tisto kar ti ni jasno):
int* a;
int* b;
b = a; // b naj kaže tja kot a (skopiraš kazalec, torej naslov)
*b = *a; // spremenljivka na katero kaže b naj dobi vrednost spremenljivke na katero kaže a (skopiraš podatke iz naslova)
Za -> si pravilno predstavljaš.

Tule je pa en velik ups (zaciklaš):
if(k_zacetek == NULL) {
k_zacetek = k_novi;
k_novi->k_nasl = k_konec;
k_novi->k_prej = k_zacetek;
...

Mogoče si malo prezakompliciral tale tvoj pristop. Razdeli si funkcijo na manjše bolj obvladljive dele. Recimo predvidevam, da imaš funkcijo za vstavljanje elementa v seznam. Uporabi jo tudi tu. Psevdo koda:
while a.not_last_element()
b.add_element(get_next_element(a));

Psevdokode je le za dve vrstici :) Ampak tudi tvojo kodo lahko lepo poenostaviš. Napiši (če je še nimaš) funkcijo za dodajanje elementa na konec seznama, ki sprejme index (sploh ne vem čemu služi ta index) in podatek, potem pa le še bereš po vrsti iz enega seznama in dodajaš v drugega.

Moravče ::

index je zato ker je to asociativni dvosmerni seznam (se ne sklicuješ na številko vozlišča ampak na ta index in sproti sortiraš po tem indexu).

Sem si še malo pogledal, na wikipediji je fajn članek o seznamih pa mi je zdaj jasno kolikor toliko, samo moraš še par stvari zgruntat ker imam zelo dolgo kodo, bom probal funkcije dodatkne naredit tako kot predlagaš :)

npr.: vstavljanje elementa (sproti se sortira) kar imam zdaj, pa bom probal skrajšat, malo veliko je teh if else :S

template <class T> //vstvi element na mesto kl
void a2seznam<T>::vstavi(int kl, const T& p)
{
	Element * k_novi;

	Element * k_trenutni;
	k_trenutni = k_zacetek;

	k_novi = new Element;
	k_novi->index = kl;
	k_novi->podatek = p;

	if(k_trenutni == NULL)
	{//potem vstaviš na začetek, in je to edini člen
		k_novi = k_zacetek;
		k_novi = k_konec;
		k_novi->k_nasl = NULL;
		k_novi->k_prej = NULL;
	}
	else { 
		while(k_trenutni->index < kl)
		{
			if(k_trenutni->k_nasl == NULL) //potem smo na koncu in skočimo ven, to obdelamo v naslednjem if
				break;
			else
				k_trenutni = k_trenutni->k_nasl;
		}

		if(k_trenutni->k_nasl == NULL) //vstavljamo na konec nepraznega seznama
		{
			k_novi->k_nasl = NULL;
			k_trenutni->k_nasl = k_novi;
			k_novi->k_prej = k_trenutni;
			//k_trenutni uporabim zato da naslednjega od novega povežem v nazaj (k_prej) z novim
			k_konec = k_novi;	
		}
		else {
			if(k_trenutni == k_zacetek) //vstavljamo na začetek nepraznega seznama
			{
				k_novi->k_nasl = k_trenutni;
				k_novi->k_prej = NULL;
				k_zacetek = k_novi;
				k_trenutni->k_prej = k_novi;
			}	
			else	//vstavljamo vmes v neprazen seznam
			{
				k_novi->k_nasl = k_trenutni->k_nasl;
				k_trenutni->k_nasl = k_novi;
				k_novi->k_prej = k_trenutni;
				//k_trenutni uporabim zato da naslednjega od novega povežem v nazaj (k_prej) z novim
				k_trenutni = k_novi->k_nasl;
				k_trenutni->k_prej = k_novi;
			}
		}
	}

} 

Gundolf ::

> asociativni dvosmerni seznam
No, to pa je en totalno neefektiven kontejner :) Ampak pustimo to, nima veze zdele. Tudi zadnja koda ima napake - že takoj na začetku najdem eno:
	k_novi = new Element;
	k_novi->index = kl;
	k_novi->podatek = p;

	if(k_trenutni == NULL)
	{//potem vstaviš na začetek, in je to edini člen
		k_novi = k_zacetek;
		k_novi = k_konec;
		k_novi->k_nasl = NULL;
		k_novi->k_prej = NULL;
	}

Verjetno si v if-u hotel narediti tole:
...
		k_zacetek = k_novi;
		k_konec = k_novi;
...


Ok, morda taprva svar, ki bi jo ločil od ostalih (ker se mi zdi da ti probleme dela) je, da bi napisal funkcijo Element::vrini_element(Element* pred, Element *za). Se pravi funkcija, ki v seznam vrine nov element med dva podana, pri tem da sta lahko tadva eden ali oba NULL. In to le vrivanje v seznam, nobenega preverjanja indexa itd. Pač poskusiš si tisto stvar, ki ti ni 100% jasna ločit od ostale navlake. Pa še koristna ti bo taka funkcija, pri navadnem vstavljanju boš le še poiskal pravo mesto ter jo poklical, isto pri kopiranju seznama.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Kiberpipa: Android srečanje, Kibi.si, 7k:nova oblika življenja, Fahrenheit 451 (Bradb

Oddelek: Novice / Android
73263 (2833) Tear_DR0P
»

[c++]Seznam

Oddelek: Programiranje
142658 (2658) Gundolf
»

Za kolko bi lahko prodal ta PC?

Oddelek: Strojna oprema
311632 (1169) opeter
»

[C++] Linker error

Oddelek: Programiranje
51286 (1286) Quikee
»

[naloga][c++] brisanje elementa

Oddelek: Programiranje
61323 (1195) rasta

Več podobnih tem