lista dwukierunkowa

0

Witam, mam problem z takim zadaniem, otóż nie jestem w stanie zrozumieć dlaczego nie działa poprawnie funkcja dodawania pozycji i jej usuwania. Poniżej w kodzie dwie linijki są umieszczone w komentarzu i wtedy dodaje się pierwsza pozycja, usuwa się, dodają się dwie kolejne i pogram ma problem, gdyż nie może dodać trzeciej pozycji. Jeśli ktoś zrozumie idee i zobaczy w czym leży (być może banalny) problem, prosiłbym o nakierowanie.

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

struct element /**< struktura oblsugujaca liste */
{
    double number;
    element* next;
    element* prev;
};
struct double_list /**< struktura pomocnicza */
{
    element* head=nullptr;
    element* tail=nullptr;
    int counter;
};
int rozmiar(double_list l)
{
    return l.counter;
}
void dodaj_tail(double_list &l, double value)
{
    element *el=new element;
    el->number=value;
    el->next=nullptr;
    el->prev=nullptr;
    if(l.tail!=nullptr)
    {
        l.tail->next=el;
        el->prev=l.tail;
    }
    else
    {
        l.head=el;
    }
    l.tail=el;
    l.counter++;
}
void dodaj_head(double_list &l, double value)
{
    element* el=new element;
    el->number=value;
    el->next=nullptr;
    el->prev=nullptr;
    if(l.head!=nullptr)
    {
        l.head->prev=el;
        el->next=l.head;
    }
    else
    {
        l.tail=el;
    }
    l.head=el;
    l.counter++;
}
void dodaj(double_list &l, double value, int position) /**< funkcja dodajaca element */
{
    if(position==(int)l.head)
    {
        dodaj_head(l, value);
    }
    if(position==(int)l.tail)
    {
        dodaj_tail(l,value);
    }
    else
    {
        element* temp=l.head;
        for(int i=1;i<position-1;i++)
            temp=temp->next;
        element* el=new element;
        el->number=value;
        el->prev=temp;
        l.counter++;
       // el->next->prev=el;
        //temp->next=el;
    }
    cout<<"Dodano element o wartosci "<<value<<" na pozycji nr. "<<position<<endl;
}
void usun_head(double_list &l)
{
    element* temp=l.head;
    if(l.counter==1)
    {
        l.tail=nullptr;
        l.head=nullptr;
    }
    else
    {
        l.head=l.head->next;
        l.head->prev=nullptr;
    }
    l.counter--;
    delete temp;
}
void usun_tail(double_list &l)
{
    element* temp=l.tail;
    if(l.counter==1)
    {
        l.tail=nullptr;
        l.head=nullptr;
    }
    else
    {
        l.tail=l.tail->prev;
        l.tail->next=nullptr;
    }
    l.counter--;
    delete temp;
}
void usun(double_list &l,int position) /**< funkcja usuwajaca element */
{
    if(position==(int)l.head)
    {
        usun_head(l);
    }
    if(position==(int)l.tail)
    {
        usun_tail(l);
    }
    else
    {
        element* temp=l.head;
        element* temp_us;
        for(int i=1;i<position-1;i++)
            temp=temp->next;
        temp_us=temp;
        //temp->next=temp_us->next;
        //temp->next->prev=temp;
        delete temp_us;
        l.counter--;
    }

}
bool czyPusta(double_list &l) /**< funkcja logiczna sprawdzajaca czy lista jest pusta */
{

}
void usun_calosc(double_list &l) /**< usuwanie calej listy */
{
    element* usuwanie=l.head;
    int pos=1;
    while(usuwanie)
    {
        usun(l,pos);
        pos++;
        usuwanie=usuwanie->next;
    }

}
int suma(double_list &l)
{
    int suma, ld, lj;
    element* obsluga=l.head;
    if(czyPusta(l)==false)
    {
         while(obsluga<=l.tail)
            {
                int liczba=obsluga->number;
                fabs(liczba);
                lj=liczba%10;
                suma+=lj;
                ld=liczba/10;
                suma+=ld;
                obsluga=obsluga->next;
            }
         return suma;
    }
    else
    {
        cout<<"Lista jest pusta"<<endl;
        return 0;
    }
}
void zadanie1(double_list &l)
{
    int s;
    ifstream plik;
    plik.open("plik1.tsk");
    char znak;
    int pos, arg;
    while(!plik.eof())
    {
        plik.get(znak);
        if(znak=='<')
        {
            plik.get(znak);
            pos=(int)znak;
            plik.get(znak);
            arg=(int)znak;
            dodaj(l,arg,pos);

        }
        if(znak=='>')
        {
            plik.get(znak);
            pos=(int)znak;
            usun(l,pos);
            cout<<"Usunieto pozycje "<<pos<<endl;
        }
        else if(znak=='!')
        {
            element* temp=l.head;
            temp=temp->next;
            while(temp)
            {
                element* lewy_el=temp->next;
                if(temp<lewy_el)
                {
                    pos=(int)temp->next;
                    usun(l,pos);
                }
                temp=temp->next;
            }
        }
    }
    plik.close();
    s=suma(l);
    cout<<"Suma cyfr wartosci bezwglednej wszystkich elemetow:  "<<s<<endl;
}

int main()
{
    double_list l;
    int opcja;
    while (1)
    {
        cout<<"\n\tMenu:\n3 - Wyjscie\n1 - Zadanie 1\n2 - Zadanie 2\n\n\nWybierz opcje i wpisz ja ponizej:\n";
        cin>>opcja;
        switch(opcja)
        {
        case 3:
            return 0;
        case 1:
            cout<<"\n\nUruchomiono zadanie 1\n\n";
            zadanie1(l);
            break;
        case 2:
            break;
        default: cout<<"Wybrano nieistniejaca opcje. Wpisz numer, ktory istnieje w Menu.\n\n\n\n";
        }
    }

    return 0;
}

0
    if(position==(int)l.head)
    {
        dodaj_head(l, value);
    }
    if(position==(int)l.tail)
    {
        dodaj_tail(l,value);
    }

Porównujesz int do wskaźnika, to jest bez sensu.

    else
    {
        element* temp=l.head;
        for(int i=1;i<position-1;i++)
            temp=temp->next;
        element* el=new element;
        el->number=value;
        el->prev=temp;
        l.counter++;
       // el->next->prev=el;
        //temp->next=el;
    }

To jest mega niewydajne, iteracja po liście jest O(n), nie powinieneś tego defaultowo robić.

Co do problemu: co mówi debugger? Jeśli chcesz pomocy to zamieść też konkretne kroki niezbędne do odtworzenia problemu.

0

To jest mega niewydajne, iteracja po liście jest O(n), nie powinieneś tego defaultowo robić.

Co do problemu: co mówi debugger? Jeśli chcesz pomocy to zamieść też konkretne kroki niezbędne do odtworzenia problemu.

Trudno mi się do tego odnieść, bo u mnie poziom bardziej amatorski. Jakbyś mógł mi rozwinąć co znaczy robić defaultowo.
Debugger pokazuje błąd w 3 liniach kodu:

// el->next->prev=el; LINE 77
dodaj(l,arg,pos); LINE 210
zadanie1(l); LINE 293

0

Nie ustawiasz next dodanemu elementowi. Wrzuć plik testowy żeby było łatwiej replikować błędy.

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