|
[ littlea @ 12.02.2006. 06:21 ] @
| Molim ko moze da izadje u susret u toku danasnjeg dana:
spremam ispit iz c-a i poceo sam da radim sa strukturama ali sve je to prilicno na niskom nivou: treba mi da mi neko dobre volje kroz primer coda objasni obradu jednostruko povezanih lista : npr. ubacivanje elemenata i sl ili recimo izvlacenja podataka recimo za listu studenata pa pravljenje proseka;
Napomena: konceptualno mi je jasan oblik jed.pove.liste (pok + el. sa null na kraju) ali me muci konkretan rad, odnosno prilicno se gubim u kodu. Pa ako neko ima nerava nek baci neki kod sa komentarima sta se dogadja (tipa pomeranje pokazivaca pri izbacivanju el. ili ubacivanju, pri vadjenju podataka, recimo ocena kako se krece, vadi i racuna i sl.)
nadam se da sam bio zadovoljavajuce razumljiv.
P.S. koje su onda bitne razlike redova? (ako imas dodatnog strpljenja) |
[ _Doctor_ @ 12.02.2006. 11:15 ] @
Pa ovako, izbunario sam jedan primer rada dodushe sa brojevima ali je logika ista.
Code:
/* Lista.h - Deklaracija paketa za rad sa listama. */
#ifndef _LISTA_H_
#define _LISTA_H_
typedef struct elem { int broj; struct elem* sled; } Elem;
Elem* naKraj(Elem** lst, int broj);
Elem* naPocetak(Elem** lst, int broj);
int saKraja(Elem** lst);
int saPocetka(Elem** lst);
int duz (Elem* lst);
void pisi(Elem* lst);
void brisi(Elem** lst);
double srVred(Elem* lst);
Elem* naMesto (Elem** lst, int mesto, int broj);
int saMesta (Elem** lst, int mesto);
Elem* obrni(Elem** lst);
Elem* uredi(Elem* lst);
#endif
/* Lista.c - Definisanje paketa. */
#include "Lista.h"
#include <stdio.h>
#include <stdlib.h>
/* Dodavanje jednog broja na kraj liste.
Ideja je da se dodje na posledji element liste
i da mu se prilepi josh jedan element.
*/
Elem* naKraj(Elem** lst, int broj){
// Ovde uvodim pomoccni pok. TEK sa kojim ccu se shetati kroz listu
Elem* tek = *lst, *novi;
// Sve dok postoji tekucci element i njegov pokazivach
// na sledecci element pomeraj se na sledecci
while(tek && tek->sled)tek=tek->sled;
novi = malloc(sizeof(Elem));
novi->sled = NULL;
novi->broj = broj;
// E sad ovde se pitam da li je tek jednak NULL
// ako jeste onda znachi da je lista prazna, shto opet znachi
// da prvi tj, LST mora da pokazuje na novi element
if(!tek)*lst = novi;
// U suprotnom prilepi ga na kraj
else tek->sled = novi;
return *lst;
}
/*
Dodavanje na pochetak
Ovde je shtos da skontash samo redosled
Kada se doda novi element koji ide na pochetak
on je u stvari prvi element, tako da njegov sledecci
element treba da bude onaj na koga pokazuje
LST pa makar LST bio NULL. I zatim samo podesish
da LST pokazuje na NOVI i gotovo
*/
Elem* naPocetak(Elem** lst, int broj){
Elem* novi = malloc (sizeof(Elem));
novi->broj = broj;
novi->sled = *lst;
*lst = novi;
return *lst;
}
/*
Ovde se problem reshava na slichan nachi kao i dodavanje na kraj.
Opet imamo TEK kojim dodjemo na poslednji element ali ovde se uvodi josh
jedan pokazivach koji pokazuje na element koji je prethodan u odnosu na
tekucci. Ovo radimo zato shto predzadnji element posle skidanja zadnjeg postaje
poslednji, logicno :), i mora mu se postaviti pok. na sledecci tj. mora se setovati
na NULL i to je sve.
*/
int saKraja(Elem** lst){
if(*lst == NULL)exit(1);
else {
Elem* tek=*lst, *pret=NULL, *stari; int broj;
while(tek && tek->sled){ pret = tek; tek=tek->sled; }
stari = tek;
broj = tek->broj;
/* Ovde se proverava da li je mozzda prethodni NULL
ako jeste onda se LST setuje na NULL jer je sada lista prazna
i onda ide ono shto sam napisao gore.
*/
if(!pret)*lst = NULL;
else pret->sled = NULL;
return broj;
}
return 0; /* Da se isposhtije sintaksa. */
}
/*
Ovde je sve jasno, nadam se.
*/
int saPocetka(Elem** lst) {
if(*lst == NULL)exit(1);
else {
Elem* stari = *lst; int broj = (*lst)->broj;
*lst = (*lst)->sled;
free(stari);
return broj;
}
return 0; /* Da se isposhtije sintaksa. */
}
/*
Ovo je jedna mala rekurzija kojom se nalazi
duzina liste.
*/
int duz (Elem* lst) {
if(!lst)return 0;
return 1 + duz(lst->sled);
}
// Ispisivanje liste
void pisi(Elem* lst) {
while(lst){
printf("%d ",lst->broj);
lst = lst->sled;
}
}
// Brisanje liste.
void brisi(Elem** lst){
Elem* stari;
while(*lst){
stari = *lst;
*lst = (*lst)->sled;
free(stari);
}
}
// Srednja vrednost elemenata liste
double srVred(Elem* lst){
double sum = 0.0; int duz = 0;
while(lst) { sum += lst->broj; duz++; lst = lst->sled; }
return duz ? sum / duz : 0;
}
// Ubacivanje na odredjeno mesto.
Elem* naMesto (Elem** lst, int mesto, int broj) {
// Prva dva if-a su chini mi se jasna.
if(mesto <= 0)naPocetak(lst, broj);
else if(mesto >= duz(*lst))naKraj(lst, broj);
else {
// Ovde dolazim na trazzeni element
// i moraju se ispovezivati pokazivachi
int i;
Elem* tek = *lst, *pret=NULL, *novi;
for(i=0; i<mesto; i++){ pret = tek; tek = tek->sled; }
novi = malloc(sizeof(Elem));
novi->sled = tek; novi->broj = broj;
pret->sled = novi;
/*
recimo da je mesto 2. Onda cce stanje pokazivacha biti
ovakvo. Tako da je to to.
lst pret tek
[]-> [][]-> [][]-> [][]-> [][0]
[][]
novi
*/
}
return *lst;
}
int saMesta (Elem** lst, int mesto) {
if(*lst){
int d = duz(*lst);
if(mesto < 0 || mesto >= d)exit(1);
if(mesto == 0)return saPocetka(lst);
else if(mesto == d)return saKraja(lst);
else {
Elem* tek = *lst, *pret=NULL, *stari; int i;
for(i=0; i<mesto; i++) { pret = tek; tek=tek->sled; }
stari = tek;
i = tek->broj;
tek=tek->sled;
pret->sled = tek;
free(stari);
return i;
}
}
return 0;
}
Elem* obrni(Elem** lst){
if(*lst){
Elem* tek = *lst, *pret=NULL, *sled;
while(tek){
sled = tek->sled;
tek->sled = pret;
pret = tek;
tek = sled;
*lst = pret;
}
}
return *lst;
}
Elem* uredi(Elem* lst){
Elem* i, *j;
for(i=lst; i; i=i->sled)
for(j=i->sled; j; j=j->sled)
if(i->broj > j->broj){
int pom = i->broj;
i->broj = j->broj;
j->broj = pom;
}
return lst;
}
/* ListaT.c - Testiranje */
#include "Lista.h"
#include <stdlib.h>
#include <stdio.h>
int main(){
Elem* lst = NULL; int kraj = 0, izb, br, ind;
while(!kraj){
printf("\n 1. Na kraj.\n"
" 2. Na pocetak.\n"
" 3. Sa kraja.\n"
" 4. Sa pocetka.\n"
" 5. Na mesto.\n"
" 6. Sa mesta.\n"
" 7. Obrni.\n"
" 8. Uredi.\n"
" 9. Duz.\n"
"10. Pisi.\n"
"11. Obrisi.\n"
" 0. Kraj.\n\n"
"Vas izbor? ");
scanf("%d",&izb);
switch(izb){
case 0: brisi(&lst); kraj = 1; break;
case 1: case 2:
printf("Broj? "); scanf("%d", &br);
switch(izb){
case 1: naKraj(&lst, br); break;
case 2: naPocetak(&lst, br); break;
} break;
case 3: case 4:
printf("Broj: %d", izb==3 ? saKraja(&lst) : saPocetka(&lst));
break;
case 5: case 6:
printf("mesto? "); scanf("%d",&ind); ind--;
switch(izb){
case 5:
if(ind < 0 || ind > duz(lst)){
printf("\n*** Nesipravan index! ****\a\n");
break;
}
printf("Broj? "); scanf("%d",&br);
naMesto(&lst, ind, br);
break;
case 6:
if(ind < 0 || ind >= duz(lst)){
printf("\n*** Nesipravan index! ****\a\n");
break;
}
printf("Broj: %d\n", saMesta(&lst, ind));
break;
}break;
case 7: obrni(&lst); break;
case 8: uredi(lst); break;
case 9: printf("Duz= %d\n", duz(lst)); break;
case 10: printf("Lista: "); pisi(lst); putchar('\n'); break;
case 11: brisi(&lst); break;
}
}
return 0;
}
Eto toliko od mene. Tebi ostaje da malo modifikujesh code prema svojim potrebama i to je to.
Podrav
[ littlea @ 12.02.2006. 11:51 ] @
hvala mnogo !! odma' se bacam na rad! :)))
[ IDE @ 12.02.2006. 12:51 ] @
evo, ako ti i ovo moze biti imalo od koristi...
/***** CPP fajl ****/
Code: #include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "LinkedList.h"
/* KOD FUNKCIJA */
/* Osnovna funkcija - poziva sve ostale funkicje */
void BasicCaller()
{
struct node* head, *a = NULL, *b = NULL;
struct node *lst1 = NULL, *lst2 = NULL , *lst3 = NULL;
int len, i;
printf("\nPOCETAK PROGRAMA!\n");
head = BuildOneTwoThree();
Push(&head, 13);
Push(&(head->next),42);
printf("Lista je:");
WriteList(head);
putchar('\n');
len = Length(head);
printf("\nDuzina liste je %d\n", len);
printf("Broj pojavljivanja broja 1 je %d.\n", Count(head,1));
printf("Element na poziciji 4 je %d\n", GetNth(head, 4));
printf("Iz liste je sa Pop obrisan element %d\n", Pop(&head));
InsertSort(&head);
WriteList(head);
WriteList1(head);
for(i=1;i<6;i++)
{
Push(&a, i);
Push(&b,i*10);
}
printf("\nAppend primjer - nadovezivanje a i b:\n");
printf("Lista a:");
WriteList1(a);
putchar('\n');
RecursiveReverse(&a);
printf("Recursive reverse a:\n");
WriteList(a);
putchar('\n');
printf("Lista b:");
WriteList1(b);
putchar('\n');
printf("Nadovezana b na a:");
Append(&a,&b);
putchar('\n');
WriteList1(a);
putchar('\n');
WriteList1(b);
putchar('\n');
printf("Rekurzivni reverse liste a:\n");
RecursiveReverse(&a);
WriteList1(a);
putchar('\n');
lst1 = BuildSpecial();
WriteList1(lst1);
putchar('\n');
lst2 = BuildDummy();
WriteList1(lst2);
putchar('\n');
lst3 = BuildLocalRef();
WriteList1(lst3);
putchar('\n');
}
/************************************************************************/
main()
{
BasicCaller();
}
/************************************************************************/
int Length(struct node* head)
{
/* Broj elemenata upisanih u listu */
int count = 0;
struct node* current = head;
/* Prvi nacin - primjena WHILE petlje */
/*
while( current != NULL )
{
count++;
current = current->next;
}
*/
/* Drugi nacin - FOR petlja */
for (current = head; current != NULL ; count++, current = current->next );
return count;
/* Treci nacin - rekurzija */
/*
if ( head == NULL )
return(0);
else
return(1+Length(head->next));
*/
} /* Kraj funkcije Length */
/***************************************************************************/
struct node* BuildOneTwoThree()
{
/* Kreiranje liste sa elementima 1,2,3 */
/* Prvi nacin - upotreba tri pokazivaca */
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = (struct node *)malloc(sizeof(struct node));
second = (struct node *)malloc(sizeof(struct node));
third = (struct node *)malloc(sizeof(struct node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
return head;
/* Drugi nacin - prihvatljiviji */
/*
struct node* pomoc = NULL;
Push(&pomoc,3);
Push(&pomoc,2);
Push(&pomoc,1);
return pomoc;
*/
}
/**************************************************************************/
void Push(struct node** headRef, int newData)
{
/* Upisivanje elementa na pocetnu poziciju u listi */
struct node* newNode;
newNode =(struct node *)malloc(sizeof(struct node));
// newNode = new struct node * ;
newNode->data = newData;
newNode->next = *headRef;
*headRef = newNode; /* headRef = &newNode; */
}
/***************************************************************************/
int Count(Lista head, int searchFor)
{
/* Koliko puta se dati broj pojavljuje u listi */
int count = 0;
Lista current = head;
/* Prvi nacin - primjena WHILE petlje */
/*
while( current != NULL )
{
if ( current == searchFor ) count++;
current = current->next;
}
return count;
*/
/* Drugi nacin - FOR petlja */
for (current = head; current != NULL ; current = current->next )
{
if ( current->data == searchFor ) count++;
}
return count;
}
/**************************************************************************/
int GetNth(Lista head, int n)
{
/* Odrediti n-ti element u listi */
Lista current = head;
int count = 0;
/* Prvi nacin - primjena WHILE petlje */
while( current != NULL )
{
if ( count == n ) return(current->data);
count++;
current = current->next;
}
assert(0);
}
/**************************************************************************/
void DeleteList(struct node** headRef)
{
/* Brisanje svih elemenata iz liste */
struct node* current = *headRef;
struct node *next;
while ( current != NULL )
{
next = current->next;
free(current);
current = next;
}
*headRef = NULL;
}
/**************************************************************************/
int Pop(struct node** headRef)
{
/* Cita prvi element liste i brise ga iz liste */
struct node* head;
int result;
head = *headRef;
assert(head != NULL);
result = head->data;
*headRef = head->next;
free(head);
return(result);
}
/*********************************************************************/
void InsertNtx( struct node** headRef, int index, int data)
{
/* umetanje podatka na poziciju datu indexom */
if ( index == 0 )
Push(headRef, data);
else
{
struct node* current = *headRef;
int i;
for (i=0;i<index-1; i++)
{
assert(current != NULL);
current = current->next;
}
assert( current != NULL );
Push(&(current->next), data);
}
}
/*************************************************************************/
void SortedInsert(struct node** headRef, struct node* newNode)
{
/* Upisivanje cvora u uredjenu listu */
struct node** currentRef = headRef;
while ((*currentRef != NULL) && ((*currentRef)->data < newNode->data))
{
currentRef = &((*currentRef)->next);
}
newNode->next = *currentRef;
*currentRef = newNode;
}
/*********************************************************************/
void InsertSort(struct node** headRef)
{
/* Uredjivanje elemenata liste u rastucu */
struct node* result = NULL;
struct node* current = *headRef;
struct node* next;
while (current != NULL)
{
next = current->next;
SortedInsert(&result, current);
current = next;
}
*headRef = result;
}
/**************************************************************************/
void WriteList(struct node* head)
{
/* Stampanje elemenata liste - rekurzivno*/
if (head != NULL)
{
printf("%d ", head->data);
WriteList(head->next);
}
}
/************************************************************************/
void WriteList1(struct node* head)
{
/* Stampanje elemenata liste - nerekurzivno*/
if ( head == NULL )
{
printf("Lista je prazna!\n");
return;
}
while (head != NULL)
{
printf("%d ", head->data);
head = head->next;
}
}
/**************************************************************************/
void Append(struct node** aRef, struct node** bRef)
{
/* Nadovezivanje liste b na listu a. b postaje NULL, a je nova lista */
struct node* current;
if(aRef == NULL)
{
*aRef = *bRef;
}
else
{
current = *aRef;
while (current->next != NULL)
{
current = current->next;
}
current->next = *bRef;
}
*bRef = NULL;
}
/*************************************************************************/
void RecursiveReverse(struct node** headRef)
{
/* Obrtanje liste u mjestu */
struct node* first;
struct node* rest;
if (*headRef == NULL) return;
first = *headRef;
rest = first->next;
if (rest == NULL) return;
RecursiveReverse(&rest);
first->next->next = first;
first->next = NULL;
*headRef = rest;
/*
WriteList(*headRef);
putchar('\n');
*/
}
/**********************************************************************/
/* Sledece tri funkcije kreiraju listu 1->2->3->4->5->6 */
struct node *BuildSpecial()
{
/* Prvi cvor dodaje se direktno na head, dok se svi ostali
cvorovi dodaju na kraj, tj. gdje pokazuje tail */
struct node *head = NULL;
struct node *tail;
int i;
Push(&head, 1);
tail = head;
for(i=2;i<=6;i++)
{
Push(&(tail->next), i);
tail = tail->next;
}
return(head);
}
struct node *BuildDummy()
{
/* Upotreba privremenog vjestackog cvora (dummy node) */
/* Moguce da taj cvor bude dio liste, pa se npr. prazna lista
ne predstavlja sa NULL vec samo sa dummy cvorom */
struct node dummy;
struct node *tail = &dummy;
int i;
dummy.next = NULL;
for(i=1;i<=6;i++)
{
Push(&(tail->next),i);
tail = tail->next;
}
return(dummy.next);
}
struct node* BuildLocalRef()
{
/* Lokalni reference-pointer, koji ukazuje na poslednji
pokazivac u listi (a ne na poslednji cvor) */
struct node *head = NULL;
struct node **lastRefPtr = &head;
int i;
for(i=1;i<=6;i++)
{
Push(lastRefPtr, i);
lastRefPtr = &((*lastRefPtr)->next);
}
return(head);
}
/****** H fajl ********/
Code:
struct node
{
int data;
struct node* next;
};
typedef struct node* Lista;
/* ZAGLAVLJA PROCEDURA I FUNKCIJA. */
/* ZA NEKE FUNKCIJE DATA SU DVA MOGUCA NACINA ZADAVANJA */
int Length(Lista head); /* int Length(struct node* head); */
struct node* BuildOneTwoThree(); /* Lista BuildOneTwoThree(); */
void Push(struct node** headRef, int newData);
/* void Push(Lista* headRef, int newData);*/
int Pop( struct node** );
int GetNth(Lista , int);
int Count(Lista head, int searchFor);
void InsertSort( struct node** );
void WriteList( struct node* );
void WriteList1(struct node* );
void Append(struct node**, struct node** );
void RecursiveReverse(struct node**);
struct node *BuildDummy();
struct node* BuildLocalRef();
struct node* BuildSpecial();
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|