Lista jednokierunkowa uporządkowana - wersja z wartownikiem

0

Sortowanie listy działa, ale nie mam pojęcia jak zrobić wersję z wartownikiem. Ktoś ma jakiś pomysł?

#include <stdio.h>
#include <stdlib.h>
 
struct el
{
    int klucz;
    struct el *nast;
};
 
typedef struct el elListy;
typedef elListy *lista;
 
void WyswietlListeP( lista _lista )
 {
     lista l = _lista;
    while ( l ){
    printf ("%d->", l->klucz);
    l = l->nast;
              }
    printf ("\n");
 }
 
void DNPL (lista *l, int i) // Dodanie na poczatek listy
{
    lista p=malloc(sizeof(elListy)) ;
    if (i>0) 
    {
        p->klucz=i;
        p->nast=*l;
        *l=p;
    }
    else
    {
        printf("Liczba jest ujemna. Podaj dodatnia:\n", i);
    }
}
 
void swap(int *a, int *b)
{
    int tmp=*a;
    *a=*b;
    *b=tmp;
}
 
void Sortowanie(lista *l)
  {
   lista p,q,s;
   for(s=q=NULL;;s=NULL)
     {
      for(p=*l;p->nast!=q;p=p->nast)
        {
         if(p->klucz>p->nast->klucz)
           {
            swap(&p->klucz, &p->nast->klucz);
            s=p->nast;
           }
        }
      if(!(q=s)) break;
     }
  }
 
int main() 
 {     
     int wybor;
    int liczba;
    struct el *l=0;
    struct el *l1=0;
    struct el *l2=0;
    int i;
 
    printf("[1] Dodanie na poczatek listy\n");
    printf("[2] Wyswietlanie listy z porzadkiem\n");
    printf("[3] Wyswietlanie listy z porzadkiem - wersja z wartownikiem\n");
    printf("[4] Wyswietl liste\n");
    printf("[5] Wyjscie z programu\n");
    do{
    printf("Wybierz: ");
    scanf("%d", &wybor);
    switch(wybor)
        {
        case 1:
            printf("Podaj liczbe: ");
            scanf("%d", &liczba);
            DNPL(&l, liczba);
        break;
        case 2:
            printf("Wyswietlanie listy z porzadkiem\n");
            Sortowanie(&l);
            WyswietlListeP(l);
           break;
           case 3:
            printf("Wyswietlanie listy z porzadkiem - wersja z wartownikiem\n");
           break;
        case 4:
            printf("Wyswietlanie listy od poczatku\n");
            WyswietlListeP(l);
            printf("\n");
        break;
        case 5:
            printf("Wyszedłes z programu!");
            return 0;
        break;
    }
    }while( wybor>=1 );
 
    return 0;
}
 
0

chodzi o to? https://pl.wikipedia.org/wiki/Sortowanie_b%C4%85belkowe#Modyfikacje_powoduj.C4.85ce_ulepszenie_czasu
Jeżeli tak to tak powinno być spoko

void Sortowanie(lista *l)
  {
   lista p,q,s;
   int bylaZmiana;

   for(s=q=NULL;;s=NULL)
     {
      bylaZmiana = 0;
      for(p=*l;p->nast!=q;p=p->nast)
        {
         if(p->klucz>p->nast->klucz)
           {   
            bylaZmiana = 1;
            swap(&p->klucz, &p->nast->klucz);
            s=p->nast;
           }
        }
      if( bylaZmiana == 0 ) break;
      if(!(q=s)) break;
     }
  }
0

Dzięki. Program działa, ale z tego co pamiętam z zajęć to chyba chodziło o wykorzystanie funkcji INT_MAX. Nie wiem czy to na samo czy wtedy inaczej będzie?

0

po pierwsze to nie funkcja po drugie co ma INT_MAX do czegokolwiek? sprawdz do czego sluzy INT_MAX pozniej zadawaj pytania ;)

0

Chodzi o takie coś jak poniżej. Jednak kompilator wyświetla błąd: "void value not ignored as it ought be to". Ktoś wie jak uniknąć tego błędu?

lista *Sortowaniewart(lista *l, int dodaj)
{
    lista *tmp=malloc(sizeof(elListy));
    lista *tmp2=l;

    if((*tmp2)->klucz>=dodaj)
        l=DNPL(l, dodaj);
    else{
        (*tmp)->klucz=dodaj;
        while((*tmp2)->klucz!=INT_MAX)
        {
            if((*tmp2)->nast->klucz>=dodaj)
            {
                (*tmp)->nast=(*tmp2)->nast;
                (*tmp2)->nast=*tmp;
                return l;
            }
            *tmp2=(*tmp2)->nast;
        }
    }
    return l;
}
 
0

Dlaczego porównujesz klucz z INT_MAX?

0

Błąd jest dlatego:

void DNPL (lista *l, int i)
{
    // ...
}

// ...
        l=DNPL(l, dodaj);
// ...

Czyli DNPL (czytelna nazwa swoją drogą) nic (void) nie zwraca, a Ty próbujesz to nic (void) zapisać do l.

Prawdopodobnie chodziło Ci o samo DNPL(l, dodaj), ale ten kod "z wartownikiem" nie ma sensu tak czy inaczej - np. dlaczego to porównanie z INT_MAX (chyba że robisz jakieś niejawne założenie o liście którego nie powiedziałeś). Dlaczego return l; w środku? Etc.

0

Dzięki za erraty, czyli funkcja, którą napisał stryku jest poprawna?

 
void Sortowanie(lista *l)
  {
   lista p,q,s;
   int bylaZmiana;
 
   for(s=q=NULL;;s=NULL)
     {
      bylaZmiana = 0;
      for(p=*l;p->nast!=q;p=p->nast)
        {
         if(p->klucz>p->nast->klucz)
           {   
            bylaZmiana = 1;
            swap(&p->klucz, &p->nast->klucz);
            s=p->nast;
           }
        }
      if( bylaZmiana == 0 ) break;
      if(!(q=s)) break;
     }
  }
0

Ostatnia instrukcja warunkowa nie robi tego co myślisz.

1

Ostatnia instrukcja warunkowa nie robi tego co myślisz.

Nie wiem co myśli @maras15, ale ostatnia instrukcja warunkowa robi to co myślał @stryku (i jest dobrze, chociaż niezbyt czytelnie).

0

Ach, teraz widzę, więc nevermind :D
Przystosowałem się do zwracania uwagi na taki styl pisania w kodach na forum i nie do końca przeanalizowałem sam algorytm.

0

Dzięki Panowie za wszystkie porady i rozwiązanie. Bardzo mi pomogliście :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1