Lista zbudowana na klasie

0

Witam,
Może jestem jakiś tępy ale doszedłem w mojej nauce programowania do list i nie mogę tego przegryźć.
W sieci jest mnóstwo przykładów ale prawie wszystkie są na strukturach a jak już jest coś na klasach to jest jakieś skomplikowane i nie wiem o co chodzi.
Czy może mi ktoś pokazać i ewentualni wytłumaczyć jeśli będę miał problem kod najprostszej listy stworzonej na klasach?
Może ona nic nie robić.
Prosił bym o klasę lista z podstawowymi metodami albo jakiś dobry link.
Aż mi głupio jak widzę, że to nie jest takie trudne ale siedzę już kilka godzin i nie idzie....

0

Prawdopodobnie wszystko będzie działać, jeżeli słówko struct zamienisz na class.

0

Ale z tego co widzę to zwykle tworzone są dwie struktury.
W funkcjach są dziwne nazwy złożone z wielu małych i dużych liter które nic mi nie mówią, jest tam mnóstwo wskaźników i po prostu gubię się i nie wiem co jest co.
Chciał bym zwykłą najprostszą pustą listę zbudowaną na klasach.
Z nazwami zmiennych typu wartosc, nastepny, poprzedni. Zamiast *aDDtoNext8219381298tilltailheadBox4
Metodami typu dodaj, wyszukaj itp
Tak chyba najłatwiej się tego nauczę.

0

Być może. Z drugiej strony na (tym) forum istnieje pewna zasada: pomagamy, naprowadzamy, ale nie piszemy (za darmo) za kogoś całych programów. Jeżeli nie rozumiesz trzech konkretnych linijek kodu to je tutaj wklej. Jeżeli nie rozumiesz większości kodu to jednak polecam wrócić do podręcznika.

0

No to inaczej:

 
class Lista
{
	string wiersz;
	Lista *next;
public:
	~Lista();
	void dodaj(Lista*,string);
};

Lista::~Lista()
{
	delete next;
}

void Lista::dodaj(Lista *l,string x)
{
	Lista *ob=new Lista;
	Lista *tmp=new Lista;
	tmp->wiersz=x;
	tmp->next=NULL;
	*ob->next=tmp;
	
}

Co mam zrobić żeby to zadziałało.
W jaki sposób mam dodać kolejny element list i jak się do niego potem odwołać.

Nie posiadam podręcznika. Uczę się z internetu i zależy mi na czasie. Ale tego z netu nauczyć się nie potrafię.
Jeśli ktoś zna jakiś dobry link na temat list na klasach to chętnie poczytam.

0
template <typename T>
class Lista
{
      private:
      T *kontener;
      int size;
      public:
      Lista(int a)
      {
            kontener=new T [a];
            size=a;
      }
      ~Lista()
      {
            delete [] kontener;
      }
      dodaje_lement(T cos)
      {
            T *buff=new T[size];
            size++;
            //przepisz kontener do buff;
            kontener=new T[size];
            kontener[size-1]=cos;
            delete [] buff;
      }
      //podobnie jak wyzej mozesz usuwac jakis element o podanym indeksie
      //zdałoby sie przeciazyc jakis operator dostepu do okreslonego elementu w kontenerze
};

Z palca klikane wiec szaleństwo to to nie jest ale ja bym tak kombinował...

1

Mylisz książkową definicję listy (lista -> element . lista lub lista -> null), z tym jak powinien zachowywać się kontener. Stwórz klasę lista, która będzie się zajmowała interfejsem, a w niej stwórz strukturę np. node, która będzie odpowiadała za element listy (czyli ma zawartość elementu i wskaźnik na kolejny element).

0

Ja bym poprosił o jasne wytłumaczenie CO i PO CO chcesz zrobić, jak najdokładniej.

0

Chce się po prostu nauczyć operować listą.
Tyle.
A co chce zrobić?
Listę zbudowaną na klasach posiadającą podstawowe metody do obsługi listy.

Może być to lista przechowująca np kolejne cyfry na kolejnych pozycjach, to bez znaczenia.

2
  1. Najpierw dowiedz się po co listę w ogóle używać. Co to jest i teoria, czysto z wikipedii, nie przeglądaj żadnych źródeł.
  2. Zainteresuj się listą stl-ową (prosty przykład) - poczytaj jak to działa, pobaw się itp.:
#include <list>

using namespace std;

int main()
{
  list<int> lista;
  lista.push_back(5);
  lista.push_front(6);
  // ... mozna tutaj sobie dodawac do usranej smierci

  // operacje na wszystkich elementach
  for (list<int>::iterator it = lista.begin(); it!=lista.end(); ++it)
    {
      // aktualny element listy na ktorym operujesz to: *it
      // do aktualnego elementu dodaje 5
      *it += 5;
    }
  return 0;
}
  1. Jeśli po obejrzeniu powyższej klasy nadal masz potrzebe, zadanie w szkole albo uczelni, żeby napisać samemu listę, to
    a) czytasz na temat wskaźników - masz się swobodnie nimi poruszać
    b) czytasz o new/delete (powinno zająć około minuty, o ile w poprzednim punkcie tego nie zrobiłeś)
    c) jeszcze raz robisz to co w punkcie 1.
    d) już powinieneś wiedzieć jak napisać
0

Może to Ci pomoże:

#include <iostream>
#include <cassert>

using namespace std;

template <class T>
class Link;

template <class T> 
class List
{
	public:
		List() : head(NULL) {}
		List(const List &source);
		virtual ~List();

		virtual void add(T value);
		virtual void deleteAll();
		T firstElement() const;
		virtual void showAll();
		virtual bool includes(T value) const;
		bool isEmpty() const;
		virtual void removeFirst();
	
	protected:
		Link<T>*head;
};

template <class T>
class Link
{
	public:
		Link <T>*insert(T _value);
	private:
		Link(T _value, Link *_next) : value(_value), next(_next) {}

		Link<T> *next;
		T value;

		friend class List<T>;
};

template <class T> Link <T> *Link<T> :: insert(T _value)
{
	new Link<T>(_value, next);
	assert(next != NULL);
	return next;
}

template <class T> void List<T> :: add(T value)
{
	head = new Link<T>(value, head);
	assert(head != NULL);
}

template <class T> T List<T> :: firstElement() const
{
	assert(head != NULL);
	return head->value;
}

template <class T> bool List<T> :: isEmpty() const
{
	return head == NULL;
}

template <class T> bool List<T> :: includes(T value) const
{
	for(Link<T> *ptr = head; ptr; ptr = ptr->next)
		if(value == ptr->value)
			return true;
	return false;
}

template <class T> void List<T> :: removeFirst()
{
	assert(head != NULL);
	Link<T> *ptr = head;
	head = ptr->next;
	delete ptr;
}

template <class T> void List<T> :: deleteAll()
{
	Link<T> *n;
	for(Link<T> *p = head; p; p = n)
	{
		n = p->next;
		delete p;
	}
	head = NULL;
}

template <class T> void List<T> :: showAll()
{
	for(Link<T> *ptr = head; ptr; ptr = ptr->next)
		std::cout << ptr->value << " ";
	std::cout << std::cout<<endl;
}

int main()
{
	List<int> *Lista = new List<int>();
	Lista->add(2);
	Lista->add(3);
	Lista->add(4);

	Lista->showAll();

	Lista->deleteAll();
	delete Lista;

	return 0;
} 
0

Dzięki wszystkim.
Szczególnie krwq, dziś pomogłeś mi już kolejny raz.
Sądzę, że lista stl'a jest bardzo fajna i funkcjonalna tylko myślę, że trochę wstyd nie umieć napisać własnej.
No teraz może już sobie poradzę.
Chyba po prostu pora zainwestować w jakiś dobry podręcznik.
Symfonia c++ będzie ok? Czy może znacie coś lepszego?

0

Wg. mnie wiedza z tego wystarczy, żeby zacząć:
http://darkcult.nazwa.pl/wiki/index.php/C%2B%2B
a później już tylko google. Thinking in C++ jest wg. mnie bardzo dobrą książką. Symfonia ma wg. mnie wadę, że wszystko jest tłumaczone trochę zbyt topornie, ale mogłem mieć takie wrażenie dlatego, że C++ jest to mój drugi język programowania. Ale jak już chcesz Symfonię to koniecznie z dopiskiem Standard.

0

O!
Teraz już trochę za późno na dokładniejsze przeglądanie ale na pierwszy rzut oka stronka się bardzo dobrze zapowiada.
Dzięki za rady.

0

Tu jest przykłada prostej listy, który zapewnia jednocześnie sortowanie danych:


#include <iostream>
using namespace std;

/* Klasy:

// PART - zawiera numer części, ewentualnie inne informacje na ich temat

// PartNode- węzeł w liście

// PartList-  lista węzłów

*/

//abstrakcyjna klasa bazowa czesi

class Part
{
    public:
    Part():itsPartNumber(1) {}
    Part(const int partNumber):itsPartNumber(partNumber) {}
    virtual ~Part() {}
    int partNumber() const {return itsPartNumber;}
    virtual void display() const = 0;

    private:
    int itsPartNumber;
};

void Part::display() const
{
    cout << "\nNumer czesci: " << itsPartNumber << endl;
}

//Czesc samochodu

class CarPart: public Part
{
    public:
    CarPart():itsModelYear(94) {}
    CarPart(int year, int partNumber);
    virtual void display() const
    {
        Part::display();
        cout << "Rok modelu: " << itsModelYear << endl;
    }

    private:
    int itsModelYear;
};

CarPart::CarPart(int year, int partNumber):
    itsModelYear(year),
    Part(partNumber)
{
}

// czesc samolotu
class AirPlanePart: public Part
{
    public:
    AirPlanePart(): itsEngineNumber(1) {}
    AirPlanePart(int engineNumber, int partNumber);
    virtual void display() const
    {
        Part::display();
        cout << "Nr silnika: " << itsEngineNumber << endl;
    }

    private:
    int itsEngineNumber;
};

AirPlanePart::AirPlanePart(int engineNumber, int partNumber):
    itsEngineNumber(engineNumber),
    Part(partNumber)
{
}

// wezel czesci
class PartNode
{
    public:
    PartNode(Part*);
    ~PartNode();
    void setNext(PartNode *node) {itsNext = node;}
    PartNode* next() const {return itsNext;}
    Part* part() const;

    private:
    Part* itsPart;
    PartNode* itsNext;
};

PartNode::PartNode(Part* part):
    itsPart(part),
    itsNext(0)
{
}

PartNode::~PartNode()
{
    delete itsPart;
    delete itsNext;
}

Part* PartNode::part() const
{
    return ((itsPart) ? itsPart : NULL);
}

// klasa partlist
class PartsList
{
    public:
    PartsList();
    ~PartsList();

    Part* find(int position, int partNumber) const;
    int count() const {return itsCount;}
    Part* firstPart() const;
    void insert(Part*);
    void iterate() const;
    Part* operator[] (int) const;

    private:
    PartNode *partHead;
    int itsCount;
};

PartsList::PartsList():
    partHead(0),
    itsCount(0)
{
}

PartsList::~PartsList()
{
    delete partHead;
}

Part* PartsList::firstPart() const
{
    return ((partHead) ? partHead->part() : NULL);
}

Part* PartsList::operator[] (int offSet) const
{
    PartNode *tempPartNode = partHead;

    if((!partHead) || (offSet > itsCount)) return NULL;

    for(int i=0; i<offSet; i++) tempPartNode = tempPartNode->next();

    return tempPartNode->part();
}

Part* PartsList::find(int position, int partNumber) const
{
    PartNode *tempPartNode = partHead;
    for(position=0; tempPartNode!=NULL; tempPartNode=tempPartNode->next(),position++)
    {
        if(tempPartNode->part()->partNumber() == partNumber) break;
    }

    return ((tempPartNode) ? tempPartNode->part() : NULL);
}

void PartsList::iterate() const
{
    if(!partHead) return;
    PartNode *tempPartNode = partHead;
    do
    tempPartNode->part()->display();
    while(tempPartNode=tempPartNode->next());
}

void PartsList::insert(Part *part)
{
    PartNode *newPartNode = new PartNode(part);
    PartNode *currentPartNode = partHead;
    PartNode *nextPartNode = 0;

    int newPartNumber = part->partNumber();
    int next = 0;
    ++itsCount;

    if(!partHead)
    {
        partHead = newPartNode;
        return;
    }

    if(partHead->part()->partNumber() > newPartNumber)
    {
        newPartNode->setNext(partHead);
        partHead = newPartNode;
        return;
    }

    for(;;)
    {
        if(!currentPartNode->next())
        {
            currentPartNode->setNext(newPartNode);
            return;
        }

        nextPartNode = currentPartNode->next();
        next = nextPartNode->part()->partNumber();
        if(next > newPartNumber)
        {
            currentPartNode->setNext(newPartNode);
            newPartNode->setNext(nextPartNode);
            return;
        }
        currentPartNode = nextPartNode;

    }
}

int main()
{
    PartsList pl;
    Part *part = 0;
    int partNumber;
    int value;
    int choice;

    while(1)
    {
        cout << "(0)Wyjscie (1)Samochod (2)Samolot: ";
        cin >> choice;
        if(!choice) break;

        cout << "New number part: ";
        cin >> partNumber;

        if(choice == 1)
        {
            cout << "Model? :";
            cin >> value;
            part = new CarPart(value, partNumber);
        }
        else
        {
            cout <<"Numer silnika: ";
            cin >> value;
            part = new AirPlanePart(value,partNumber);
        }

        pl.insert(part);

    }

    pl.iterate();
    return 0;
}

Przeanalizuj kod a na pewno zrozumiesz :) Ogólnie chodzi o to że lista składa się z węzłów, każdy węzeł zawiera wskaźnik do następnego (lista jednokierunkowa), niektóre zawierają również wskaźnik do poprzedniego (lista dwukierunkowa). Każdy węzeł to taki jakby pojemnik na dane które mamy przechowywać. Do operacji na liści zwykle tworzy się osobną klasę która zapewnia dla niej interfejs oraz zawiera wskaźnik do głowy listy ( pierwszego węzła).

0

Mi się problem wydał ciekawy, więc postanowiłem sobie napisać...
Może się autorowi przyda, ale szału nie ma, d**y nie urywa... :D

#include <iostream>
using namespace std;

template <class T>
class kontener
{
      private:
            T *x;
            long long int size;
      public:
            kontener()
            {
                  x = new T [0];
                  size = 0;
            }
            kontener(long long int s)
            {
                  x = new T [s];
                  size = s;
            }
            ~kontener()
            {
                  delete [] x;
            }
            void add(T cos)
            {
                  long long int i=0;
                  T *buff = new T [size];
                  for (i=0;i<size;i++) buff[i] = x[i];
                  delete [] x;
                  x = new T [++size];
                  for (i=0;i<size-1;i++) x[i] = buff[i];
                  delete [] buff;
                  x[size-1] = cos;
            }
            void add(T cos, long long int index)
            {
                  long long int i=0;
                  T *buff = new T [size];
                  for (i=0;i<=size;i++) buff[i] = x[i];
                  delete [] x;
                  x = new T [++size];
                  for (i=0;i<index;i++) x[i] = buff[i];
                  x[index] = cos;
                  for (i=index+1;i<size;i++) x[i] = buff[i-1];
                  delete [] buff;
            }
            void erase(long long int index)
            {
                  long long int i=0,in=0;
                  T *buff = new T [size];
                  for (i=0;i<size;i++) buff[i] = x[i];
                  delete [] x;
                  x = new T [--size];
                  for (i=0;i<=size;i++)
                  {
                      if (i != index)
                      {
                          x[in] = buff[i];
                          in++;
                      }
                  }
                  delete [] buff;
            }
            long long int howbig()
            {
                  return(size);
            }
            void clear()
            {
                  delete [] x;
                  x = new T [0];
                  size = 0;
            }
            T & operator[] (const long long int & index)
            {
                  return(x[index]);
            }
};

int main()
{
      long long int i=0;
      kontener <int> elo;
      for (i=1;i<=10;i++) elo.add(10*i); //dodaje elementy do tablicy na koniec

      cout<<"Elementy tablicy:\n";
      for (i=0;i<elo.howbig();i++)cout<<elo[i]<<"\n";   //wypisywanie kontenera
      
      elo.erase(8);               //usunie z kontenera element o zadanym indeksie
      elo[6]=600;                 //wiadomo
      elo.add(-12,2);             // doda element -12 do kontenera w miejscu zadanego indeksu - 2

      
      cout<<"Elementy tablicy:\n";
      for (i=0;i<elo.howbig();i++)cout<<elo[i]<<"\n";
      
      elo.clear();               //usunie wszystkie elementy z wektora
      
      cin.get();
      return(0);
}

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