Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Jednostruko povezane liste?

[es] :: C/C++ programiranje :: Jednostruko povezane liste?

[ Pregleda: 3570 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

littlea
Marko Jankovic
Beograd

Član broj: 36334
Poruke: 5
*.dial.b92.net.



Profil

icon Jednostruko povezane liste?12.02.2006. u 06:21 - pre 221 meseci
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)
 
Odgovor na temu

_Doctor_
Beograd

Član broj: 68915
Poruke: 12
*.ptt.yu.



Profil

icon Re: Jednostruko povezane liste?12.02.2006. u 11:15 - pre 221 meseci
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
Svet je pun budala koje misle da je svet pun budala !
 
Odgovor na temu

littlea
Marko Jankovic
Beograd

Član broj: 36334
Poruke: 5
*.dial.b92.net.



Profil

icon Re: Jednostruko povezane liste?12.02.2006. u 11:51 - pre 221 meseci
hvala mnogo !! odma' se bacam na rad! :)))
 
Odgovor na temu

IDE

Član broj: 53403
Poruke: 586
*.crnagora.net.



Profil

icon Re: Jednostruko povezane liste?12.02.2006. u 12:51 - pre 221 meseci

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();


there's something out there
waiting for us,
and it ain't no man...
 
Odgovor na temu

[es] :: C/C++ programiranje :: Jednostruko povezane liste?

[ Pregleda: 3570 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.