dodawanie,usuwanie,zliczanie,odwracanie elementow w liscie jednokierunkowej

0

Witam!
Mam napisać program wykorzystujący następujące funkcje przetwarzania uporządkowanej niemalejąco listy jednokierunkowej niecyklicznej, zawierającej w polu danych wartości całkowitoliczbowe:
a) wstaw, dodającą do listy (we właściwe miejsce) nowy element, zawierający wprowadzaną z klawiatury liczbę całkowitą; prototyp funkcji jest następujący:
void wstaw(Node **root, int wartosc);

b) usun, usuwającą z listy wszystkie elementy, zawierające wprowadzaną z klawiatury liczbę całkowitą; prototyp funkcji jest następujący:
void usun(Node **root, int wartosc);

c) policz, dodającą na początek listy węzeł, zawierający (w polu danych) liczbę pozostałych elementów listy; prototyp funkcji jest następujący:
void policz(Node **root);
Drugi program z ktorym potrzebuje pomocy:
odwraca zadaną (z klawiatury) jednokierunkową listę niecykliczną, bez wykorzystywania dodatkowej listy lub tablicy; prototyp funkcji jest następujący:
void odwroc(Node **root);

Udało mi sie dojsc do etapu dodawania i usuwania elementow jednak program ma problem z usunieciem pierwszego elementu. Prosiłbym o poprawienie danego kodu oraz o wszelkie wskazówki,naprowadzenia badz gotowe kody do pozostałych czesci zadania.(funkcja policz oraz funkcja odwracajaca elementy). Z gory dziekuje ;)

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>  

struct Node {
		int dane;
		struct Node *next;
};

typedef struct Node *NodePtr;
 
// Prototypy funkcji
void wstaw(Node **root, int wartosc);
void usun(Node **root, int wartosc);
void wyswietl(Node **root);


int main(void)
{
NodePtr poczListy; int Znak;
struct Node *biezacyPtr, *elementPtr;	

 // Tworzenie listy
	poczListy=NULL;
	printf("Wprowadz znak: ");
	scanf("%d", &Znak);
	while (Znak!=-1) {          //-1 konczy tworzenie listy
		wstaw(&poczListy, Znak);
		printf("Wprowadz kolejny znak: ");
		scanf("%d", &Znak);
	}
	printf("Koniec tworzenia listy\n");
	
	wyswietl(&poczListy);
	
	printf("\nPodaj element do usuniecia: ");
	scanf("%d", &Znak);
	usun(&poczListy, Znak);
	
//Przeglądanie listy
    wyswietl(&poczListy);	
 
    
    
    system("PAUSE");
	return 0;
}

// Definicje funkcji
void wstaw(Node **root, int wartosc) {
      struct Node *tmp, *newPtr;
      
      newPtr = (struct Node *)malloc(sizeof(Node));
      newPtr->dane = wartosc;
      newPtr->next = NULL;
      
      if (!*root) *root=newPtr;
      else {
           tmp = *root;
           if (wartosc <= tmp->dane) {
              newPtr->next = *root;
              *root = newPtr;     
           } else {
             while ((tmp->next)&&(tmp->next->dane <= wartosc)) tmp = tmp->next;
             if (!tmp->next) tmp->next = newPtr;
             else {
                  newPtr->next = tmp->next;
                  tmp->next = newPtr;     
             }       
           }
      }     
}

void usun(Node **root, int wartosc) {
      struct Node *pom, *tmp;
      
      // sprawdzamy czy lista zawiera jakies elementy
      if (!*root) printf("Lista jest pusta\n");
      else {
           tmp = *root;
           while (tmp->next) { // przemieszczamy sie po liscie
                 if ((*root)->dane == wartosc) { // gdy usuwamy pierwszy element
                    if ((*root)->next) *root = (*root)->next;
                    free(*root); 
                 } else
                 if (tmp->next->dane == wartosc) {
                    pom = tmp->next;
                    tmp->next = tmp->next->next;
                    free(pom); // usuniecie elementu
                 } else if (tmp->next) tmp = tmp->next; // gdy usuniety zostal ostatni element listy
           }
           printf("Usunieto\n");     
      } 
}

void wyswietl(Node **root) {
    struct Node *tmp;
    
    tmp = *root;
 	printf("\nPrzegladanie listy\n");
	while (tmp) {
		printf("%d\n",tmp->dane);
		tmp=tmp->next;
	}
	printf("Koniec przegladania listy\n");    
}

0

Popatrz na linijkę free(*root);. Który element listy zwalniasz? Pierwszy? Nie. Bo przesuwasz wskaźnik *root o jedną pozycję dalej (do drugiego elementu) i go zwalniasz. Cała lista jest już do niczego. Żeby było ciekawiej, to tmp wciąż wskazuje na pierwszy element (który już wskazuje w kosmos, bo drugiego elementu już przecież nie ma). Możesz zrobić tak:

tmp = (*root)->next;   //do tmp przypisujesz drugi element listy
free(*root);           //zwalniasz pierwszy element
*root = tmp;          //teraz *root wskazuje poprawnie na drugi element listy (który staje się pierwszym)

Teraz i *root, i tmp wskazują na drugi element. Ten kod będzie działać nawet, jeżeli lista ma 1 element. Zauważ, że wtedy oba wskaźniki będą wskazywać na NULL.

0

Napisałem (oczywiscie nie wiem czy poprawnie) funkcje odwracającą elementy w liście. Mam problem z jej wyświetleniem. Prosiłbym o pomoc.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>  
 
struct Node {
                int dane;
                struct Node *next;
};
 
typedef struct Node *NodePtr;
 
// Prototypy funkcji
void wstaw(Node **root, int wartosc);

void wyswietl(Node **root);
void odwroc(Node **root);
 
int main(void)
{
NodePtr poczListy; int Znak;
struct Node *biezacyPtr, *elementPtr;        
 
 // Tworzenie listy
        poczListy=NULL;
        printf("Wprowadz znak: ");
        scanf("%d", &Znak);
        while (Znak!=-1) {          //-1 konczy tworzenie listy
                wstaw(&poczListy, Znak);
                printf("Wprowadz kolejny znak: ");
                scanf("%d", &Znak);
        }
        printf("Koniec tworzenia listy\n");
 
        wyswietl(&poczListy);
 
        
 
//Przeglądanie listy
    wyswietl(&poczListy);        
 
 
 
    system("PAUSE");
        return 0;
}
 
// Definicje funkcji
void wstaw(Node **root, int wartosc) {
      struct Node *tmp, *newPtr;
 
      newPtr = (struct Node *)malloc(sizeof(Node));
      newPtr->dane = wartosc;
      newPtr->next = NULL;
 
      if (!*root) *root=newPtr;
      else {
           tmp = *root;
           if (wartosc <= tmp->dane) {
              newPtr->next = *root;
              *root = newPtr;     
           } else {
             while ((tmp->next)&&(tmp->next->dane <= wartosc)) tmp = tmp->next;
             if (!tmp->next) tmp->next = newPtr;
             else {
                  newPtr->next = tmp->next;
                  tmp->next = newPtr;     
             }       
           }
      }     
}
 


 
void wyswietl(Node **root) {
    struct Node *tmp;
 
    tmp = *root;
         printf("\nPrzegladanie listy\n");
        while (tmp) {
                printf("%d\n",tmp->dane);
                tmp=tmp->next;
        }
        printf("Koniec przegladania listy\n");    
}
   
   
   
   
void odwroc(Node ** root)
{
Node * ptr,*pre = 0, *next;
ptr = *root;
next = ptr->next;
while(ptr->next)
{
ptr-> next = pre;
pre = ptr;
ptr = next;
next = next-> next;
}
*root = ptr;
} 
0

Funkcja odwroc wygląda na pierwszy rzut oka OK. Jednak takie pytanko: gdzie wywołujesz tę funkcję? Bo jak jej nie wywołujesz, to nie dziwne, że nie działa :D

0

Własnie w tym problem bo gdy ja wywoływałem to nie chciała działąc dlatego prosiłbym o pomoc w tym temacie.(zapewne źle ja wywoływałem).

0

Zauważ, że wartość next ostatniego elementu (po odwróceniu pierwszego) po zakończeniu procedury wskazuje na 0 (nic). Na końcu procedury dopisz: ptr->next = pre;, aby ten ostatni (już pierwszy) element wskazywał na przedostatniego (tzn. drugiego po odwróceniu). Bez tego zobaczysz tylko jeden element listy.

0

Dzieki wielkie ;) a co z funkcja policz? NIe ma pojecia jak sie za nia zabrac.

0

Jak dodać element na początek listy, pewnie wiesz (wystarczy utworzyć nowy obiekt X, przypisać jego parametr next do poprzedniego początku listy i zamienić wskaźnik na początek listy na &X). A żeby policzyć wszystkie elementy, to jest prosto: ustawiasz sobie jakiś licznik na 0, chodzisz po kolejnych elementach listy i zwiększasz licznik o 1 przy każdym elemencie. Wystarczy to połączyć i masz funkcję.

0

A czy moglbys to napisac w formacie kodu? Bo mi wychodza same błędy.

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