Jednostruko spregnuta lista teorija

POREĐENJE LISTE NIZA

 

Podaci u nizu podataka  su smešteni sekvencijalno u operativnoj memoriji. Ukoliko želimo da ubacimo odnosno izbacimo neki element iz niza moramo da izvršimo pomeranje svih elemenata niza.

Jednostruko spregnuta lista je dinamička strukutura podataka koja služi za predstavljanje nizova podataka. Pošto elementi liste ne moraju da budu smešteni u uzastopne memorijske lokacije ubacivanje novog elementa u listu i izbacivanje elementa iz liste ne iziskuje pomeranja podataka   Loša strana liste u odnosu na niz osim u većem stepenu složenosti realizacije je što ne poseduje mehanizam indeksnog pristupa elementu liste. Takođe svaki element liste mora da sadrži još jedan dodatan podatak a to je pokazivač na naredni element liste.

ELEMENTI LISTE

Elementi liste su tipa strukture koja sadrži najmanje dva polja. Jedno od polja je pokazivač na sledeći element liste. Druga polja čine korisni podaci.

//Primer definisanja novog tipa podatka tip strukture koja
//se koristi za definsanje promenljivih koji će biti elementi liste.
typedef struct elem{
       int broj; //korisni podatak
       struct elem * sled;  // pokazivač na sledeći element liste
}Elem; 

OPERACIJE NAD LISTOM

Sa listom se mogu obaviti sledeće osnovne operacije

1)      Inicijalizacija liste

2)      Unos novog elementa u listu

3)      Pretraživanje liste (pronalaženje određenog elementa u listi)

4)      Listanje liste (prikaz svih elemenata liste)

5)      Brisanje elementa iz liste

6)      Brisanje čitave liste

 

INICIJALIZACIJA LISTE

Da bi se uspešno pristupilo elementima liste potrebno je da postoji promenljiva koja će da pokazuje na početak liste odnosno da sadrži adresu prvog element liste. Pokazivač na početak liste se naziva još i glava liste.

// pokazivač na prvi element liste, glava liste
Elem *glava =NULL; 
//Početna vrednost glave liste je NULL 
//što označava da je lista na početku prazna.
//Funkcija
void Init(Elem **glava)
{
	*glava=NULL;
} 

DODAVANJE NOVOG ELEMENTA NA POČETAK LISTE

 

U ovom slučaju bilo da je lista prazna ili ne pokazivač u okviru novog elementa liste će prvo pokazati na glavu liste a potom će glava liste da promeni vrednost  tako što će pokazivati na novi element liste. Glava uvek pokazuje na prvi element liste.

void UnosNaPocetak(Elem **glava, int broj)
{
	Elem *novi;

	novi = (Elem *) malloc(sizeof(Elem));
	novi->broj = broj;
	novi->sled = *glava;
	*glava = novi;
}

DODAVANJE NOVOG ELEMENTA NA KRAJ LISTE

U ovom slučaju moramo da koristimo pomoćnu proemenljivu tek pomoću koje se krećemo kroz listu.

Postoje  dve mogućnosti prilikom dodavanja novog elementa :

1) ukoliko je lista prazna glava treba da pokazuje na novi element.

2) Ukoliko lista nije prazna potrebno je pomerati se kroz listu pomoću promenljive tek sve dok tek->sled ne dobije vrednost NULL.

void UnosNaKraj(Elem **glava, int broj)
{
    Elem *novi, *tek = *glava;

    novi = (Elem *) malloc(sizeof(Elem));
    novi->broj = broj;
    novi->sled = NULL;
    if(*glava==NULL)
       *glava = novi;
    else{
         while(tek->sled!=NULL)
             tek=tek->sled;
         tek->sled = novi;
    }
}

DODAVANJE NOVOG ELEMENTA U LISTU AKO JE LISTA UREĐENA U RASTUĆEM REDOSLEDU

U ovom slučaju moramo da koristimo dve pomoćne promenljive tek i pret pomoću kojih se krećemo kroz listu.

Postoje  četiri mogućnosti prilikom dodavanja novog elementa:

1) ukoliko je lista prazna glava treba da pokazuje na novi element.

2) novi element treba da bude pozicioniran na početak liste uslov je da pret ima vrednost NULL ili tek ima vrednost glava

3) novi element treba da bude pozicioniran na kraj liste uslov je da tek ima vrednost NULL

4) novi element treba da bude pozicioniran negde u sredini liste uslov je da je vrednost novog elementa manja od vrednosti tek elementa (u slučaju liste uređene u rastućem redosledu).

void Unos(Elem **glava, int broj)
{
	Elem *novi,*pret=NULL, *tek=*glava;

	novi = (Elem *) malloc(sizeof(Elem));
	novi->broj = broj;
	novi->sled = NULL;
	
	if(*glava==NULL)
	{
	   printf("prvi element");
	   *glava = novi;
	}
    
    else
    {
       //susedni kod
    }
}
//prolazak kroz listu dok su uslovi zadovoljeni
while(tek!=NULL && broj> tek->broj)
{
    pret=tek;
    tek=tek->sled;
}
//dodavanje na pocetak liste
if(pret==NULL)
{
    printf("na pocetak");
    novi->sled = *glava;
    *glava = novi;
}
//dodavanje na kraj liste	
else if(tek==NULL) 
{
    printf("na kraj");
    pret->sled = novi;
}
// dodavanje na sredini liste
else
{
    printf("u sredinu");
    pret->sled = novi;
    novi->sled = tek;
}

PRETRAŽIVANJE LISTE (PRONALAŽENJE ODREĐENOG ELEMENTA U LISTI)

Lista može da se pretražuje  samo sekvencijalno. U slučaju da je lista uređena onda je pretraživanje malo efikasnije. 

int Pretazivanje(Elem * glava, int br)
{
	Elem * tek = glava;
	int i=1;
	while(tek!=NULL && br>tek->broj)
	{
		tek=tek->sled;
		i++;
	}

	if(tek==NULL || br!=tek->broj)
		return -1;
	else
		return i-1;
}

LISTANJE LISTE

Listanje liste služi za prikazivanje svih elemenata u listi počevši od prvog elementa. 

void Listanje(Elem *glava)
{
	Elem * tek;
	printf("\nBrojevi u listi su:");
	for(tek=glava; tek!=NULL; tek=tek->sled)
	{
		printf("%d ",tek->broj);
	}
}

BRISANJE ELEMENTA IZ LISTE

Postoje  tri mogućnosti prilikom brisanja elementa iz liste:

1) element se ne nalazi u listi.

2) kada je traženi element na početku liste

3) kada  traženi element nije na prvoj poziciji u listi 

void BrisanjeEl(Elem ** glava, int br)
{
	Elem * tek = *glava, *pret=NULL;
	
	while(tek!=NULL && br>tek->broj)
	{
		pret = tek;
		tek=tek->sled;
		
	}

	...
}
if(tek==NULL || br!=tek->broj)
    printf("\nElement se ne nalazi u listi");
//brisanje prvog elementa liste
else if(tek==*glava)
{	
    *glava = tek->sled;
    free(tek);
}
else
{
	 pret->sled = tek->sled;
	 free(tek);
}

BRISANJE SVIH ELEMENATA IZ LISTE

void BrisanjeListe(Elem ** glava)
{
	Elem *tek = *glava;
	while(*glava!=NULL )
	{
		*glava=(*glava)->sled;
		free(tek);
		tek= *glava;
	}
}
Made with Slides.com