[c++] przeszukiwanie list jednokierunkowych

#include "baza.h"

#include 

using namespace std;



ANIMAL *root; //przechowuje adres pierwszego elementy listy

ANIMAL *current;/// przechowuje biezacy element listy


ANIMAL *GetFirst()//Zwraca adres pierwszego elementu listy i ustawia wskaznik current na pierwszy element

{

  current=root;

  return root;

}


void Initialize() //funkcja inicjalizuje listę

{

  root=new ANIMAL; //tworzymy pierwszy element listy - root

  root->Name[0]=0; //wpisujemy dowolne dane do struktury

  root->LatinName[0]=0;

  root->Group[0]=0;

  root->Legs=0;

  root->Environment[0]=0;

  root->Next=NULL; //root jest ostatnim elementem listy zatem wskaĹşnik "Next" ma wartość NULL

  current=root; //ustawiamy wskaznik "current" listy na element "root"

}


void PrintData(ANIMAL* animal) //wyswietla informacje zawarte w rekordzie

{

  cout<< "Nazwa: " << animal->Name<< endl << "Nazwa lacinska: " << animal->LatinName << endl;

  cout<< "Grupa: " << animal->Group<< endl << "Liczba konczyn: " << animal->Legs << endl;

  cout<< "Srodowisko wystepowania: " << animal->Environment <
}


ANIMAL *GetNext() //zwraca element kolejnego elementu w liscie wzgledem pokazywanego przez "current"

{

 return current->Next;

}


ANIMAL *GetLast() //zwraca adres ostatniego elementu w liscie

{

 while(current->Next!=NULL){

 current=GetNext();

 }

 return current;

}


ANIMAL *AddAnimal() //dodaje rekord do listy

{

 current=GetLast();

 ANIMAL*tmp= new ANIMAL;

 current->Next=tmp;

 tmp->Next=NULL;

 return tmp;

}


void DodajZwierze() //pobiera od uzytkownika dane zwierzecia i dodaje je do bazy(...)

{

 ANIMAL*a;

 a=AddAnimal();

 cout<<"podaj nazwe: \n";

 cin>>a->Name;

 cout<<"podaj łacińśka nazwe: \n";

 cin>>a->LatinName;

 cout<<"podaj grupe: \n";

 cin>>a->Group;

 cout<<"podaj ilosc nog: \n";

 cin>>a->Legs;

 cout<<"podaj środowisko: \n";

 cin>>a->Environment;


}


void showAll(){//wyswietla wszystkie elementy listy

 current=root;

 while(current->Next!=NULL){

 current=current->Next;

 PrintData(current);

 system("pause");

 }

}


ANIMAL *FindByNameAndGroup(char *name, char *group) //wyszukuje rekord po nazwie i grupie

{

    current=root;

        do

        {

                if(strcmp(current->Name,name)==0&&strcmp(current->Group,group)==0)                      

                        return current;                 

        }while(GetNext()==NULL);


        return NULL;

}




void Delete(ANIMAL *element) //usuwa element z listy

{

 	        GetFirst();

        if(root==element)

        {

                root=element->Next;

                delete element;

                GetFirst(); 

        }

        do

        {


                if(current->Next==element)

                {

                        current->Next=element->Next;

                        delete element;

                }

        }while(GetNext()==NULL);

}



int DeleteByNameAndGroup(char *name, char *group) //wyszukuje rekord po nazwie i grupie i usuwa go

{

 ANIMAL*element=FindByNameAndGroup(name,group);

Delete(element);

current=current->Next;

return 1;

}


void DeleteAll(){ // usuwa wszystkie elementy z listy

 	  ANIMAL *tmp;


  	  while (root->Next!= NULL){

	  		  tmp = root; 

       	  root = tmp->Next;  

       	  delete tmp; 

     } 

}



void Szukaj() //wyszukuje rekord po nazwie (wyswietlanie komuniaktów - interfejs uzytkownika)

{

  char Nazwa[20],Grupa[20];

  cout<< "Wprowadz nazwe: ";

  cin>>Nazwa;

  cout<<"Podaj grupe (ssak, ptak, ryba, gad, plaz): ";

  cin>>Grupa;

  ANIMAL *zwierze=FindByNameAndGroup(Nazwa,Grupa);

  if (zwierze!=NULL)

    PrintData(zwierze);

  else cout<<"Podane zwierze nie istnieje w bazie"<
    system("PAUSE");

}


void UsunZwierze() //pobiera od uzytkownika nazwe i typ zwierzecia i usuwa je z bazy(...)

{

  char Nazwa[20],Grupa[20];

  cout<< "Wprowadz nazwe: ";

  cin>>Nazwa;

  cout<<"Podaj grupe (ssak, ptak, ryba, gad, plaz): ";

  cin>>Grupa;

  if (DeleteByNameAndGroup(Nazwa,Grupa)) cout << "Zwierze zostalo usuniete z bazy" <
  else cout<<"Podane zwierze nie istnieje w bazie"<
  system("PAUSE");

}


void WyswietlMenu()

{

  system("CLS") ;

  cout<<"MENU:"<
  cout<<"1- Nowe zwierze" <
  cout<<"2- Usun zwierze" <
  cout<<"3- Szukaj" <
  cout<<"4- pokaz wszystko"<
  cout <<"x- koniec" <
}

lub czytelniejsze ->

http://www.wklejto.pl/141363

program ma wyszukiwać pozycje i ja wyświetlać ( nie znajduje podanej wcześniej pozycji)

oraz usunąć podana przez użytkownika pozycje(wyświetla ze usunął, a wcale tego nie robi)

problem leży w liniach 82-133

obstawiam ze jest to problem tylko funkcji find

deleteall działa bez zarzutów, delete jest przepisana, wiec zostaje problem z funkcja findbynameandgroup

moglby ktos wskazac blad :?:

Na pierwszy rzut oka to

while(GetNext()==NULL);

powyższy warunek nie powinienem być odwrotny?

Przyjrzę się jeszcze temu kodowi ale wydaje mi się że to jest to.

niestety to nie to…

E: jednak to było to , brakowało tylko jeszcze warunku else :wink:

Dodane 09.12.2012 (N) 21:48

ostatnia prośba o pomoc :>

update kodu

'>http://www.wklejto.pl/141416

linie miedzy 98 a 122

mogę usuwać pojedyncze elementy oprócz ostatniego?

jakieś pomysły?

Projekt jest beznadziejny brakuje ci czegoś takiego:

stuct ANIMAL_LIST

{

ANIMAL *first,*last;

};

ANIMAL_LIST lista={0,0};

Przy takiej strukturze nie potrzebujesz funkcji: initialize(), GetLast()

Wszystkie funkcje się uproszczają, np:

ANIMAL *AddAnimal() //dodaje rekord do listy

{

return lista.last=(lista.last?lista.last->next:lista.first)=new ANIMAL;

}

Jeżeli chcesz też łatwo usuwać to zrób listę dwukierunkową, ale to nie koniecznie.

tak teraz nas ucza :wink:

dostalismy pusty szablon tylko naglowki funkcji , reszte mielismy sami wypelnic…

w kazdym razie dziekuje za pomoc

A kto ci przeszkadza przy tych samych funkcjach zrobić:

ANIMAL *first,*last;

I dalej zrobić prawie (bo ze zmiennymi globalnymi) po ludzku.

int DeleteByNameAndGroup(char *name, char *group) //wyszukuje rekord po nazwie i grupie i usuwa go

{

 ANIMAL*element=FindByNameAndGroup(name,group);

Delete(element);

current=current->Next;

return 1;

}

Problem jest w linijce current=current->Next; Dostajesz NullPointerException ponieważ current do którego się odwołujesz jest w tym przypadku nullem. Przeanalizuj sobie w debuggerze swój kod:

ln.112 current->Next=element->Next;

W przypadku usuwania ostatniego element->next jest nullem, po wykonaniu tej linijki current->next tez jest nullem. Potem się wykonuje:

ln.115 while(GetNext()==NULL);

Które po wywołaniu funkcji GetNext() podstawia pod current to co było pod current->next, co jak już wyżej napisałem jest teraz nullem. Potem wracasz do funkcji DeleteByNameAndGroup i w linijce 123 robisz current->next, problem w tym ze current jest nullem. Dodatkowo masz błędnie oprogramowane usuwanie w przypadku gdy element jest rootem i jest jednocześnie ostatnim elementem listy. Twój root stanie się wtedy NULLEM i każde kolejne odwołanie spowoduje NPE. Powinieneś sprawdzać za każdym razem czy lista nie jest pusta zanim zaczniesz po niej iterować. EDIT:

void Delete(ANIMAL *element) //usuwa element z listy

{

                current=root;

        if(root==element)

        {

                root=element->Next;

                delete element;

                current=root; 

        }

        do

        {


                if(current->Next==element)

                {

                        current->Next=element->Next;

                        delete element;

                }

        }while(GetNext()==NULL);

}

Źle sprawdziłem :x GetNext nie przesuwa current tylko robi current->next. Stary ty tutaj w ogóle nie przesuwasz wskaźnika current czyli nawet nie iterujesz się po liście :smiley: chcesz mi powiedzieć że masz na liście 10 elementów i usuwa Ci 9? Czy że masz dwa i nie usuwa Ci ostatniego?

Brakuje Ci current = current->next gdzieś w tym do while.