Bubble сортировать шаблон списка ссылок - PullRequest
0 голосов
/ 03 ноября 2010

Я пытаюсь отсортировать связанный список. У меня проблемы с конст. Это не позволит мне присвоить переменную, которая является константой, что она и должна делать. Тем не менее, я не знаю, как обойти это? Буду признателен за любую помощь.

Это все в одном заголовочном файле, функция сортировки также, я постараюсь вытащить его, чтобы его было легко найти:

void LinkedList<T>::BubleSort()
{

T temp;
ListElement<T>* cur = head;

    const ListElement<T>* forward = head->Next();


while(cur)
{
    while(forward)
    {

        if(cur->Datum() > forward->Datum())
        {

                  temp = cur->Datum();
                  cur->Datum() = forward->Datum();
                  forward->Datum() = temp;
        }
    }
}

}

Ошибки, которые я получаю

ошибка C3892: 'cur': нельзя присвоить переменную, которая является постоянной при компиляции функции-члена шаблона класса 'void LinkedList :: BubleSort (void)' см. ссылку на экземпляр шаблона класса 'LinkedList', который компилируется

Конечно, если я не могу этого сделать, я просто не знаю, как это обойти.

Вот заголовочный файл, в котором находится вся информация и функция сортировки:

#include  <typeinfo>

template <class T>
class LinkedList;

template <class T>
class ListElement
{
T datum;
ListElement* next;

ListElement (T const&, ListElement*);
public:
T const& Datum () const;
ListElement const* Next () const;

friend class    LinkedList<T>;  
};

template <class T>
class LinkedList
{
ListElement<T>* head;
ListElement<T>* tail;
public:
LinkedList ();
~LinkedList ();

LinkedList (LinkedList const&);
LinkedList& operator = (LinkedList const&);

ListElement<T> const* Head () const;
ListElement<T> const* Tail () const;
bool IsEmpty () const;
T const& First () const;
T const& Last () const;

void BubleSort();
void Prepend (T const&);
void Append (T const&);
void Extract (T const&);
void Purge ();
void InsertAfter (ListElement<T> const*, T const&);
void InsertBefore (ListElement<T> const*, T const&);
};

template <class T>
ListElement<T>::ListElement (
T const& _datum, ListElement<T>* _next) :
datum (_datum), next (_next)
{}

template <class T>
T const& ListElement<T>::Datum () const
{ return datum; }

template <class T>
ListElement<T> const* ListElement<T>::Next () const
{ return next; }



template <class T>
LinkedList<T>::LinkedList () :
head (0),
tail (0)
{}


template <class T>
void LinkedList<T>::Purge ()
{
while (head != 0)
{
ListElement<T>* const tmp = head;
head = head->next;
delete tmp;
}
tail = 0;
}

template <class T>
LinkedList<T>::~LinkedList ()
{ Purge (); }



template <class T>
ListElement<T> const* LinkedList<T>::Head () const
{ return head; }

template <class T>
ListElement<T> const* LinkedList<T>::Tail () const
{ return tail; }

template <class T>
bool LinkedList<T>::IsEmpty () const
{ return head == 0; }



template <class T>
T const& LinkedList<T>::First () const
{
if (head == 0)
    throw std::domain_error ("list is empty");
return head->datum;
}

template <class T>
T const& LinkedList<T>::Last () const
{
if (tail == 0)
    throw std::domain_error ("list is empty");
return tail->datum;
}
/**********************************************/

template <class T>

void LinkedList<T>::BubleSort()
{

T temp;
ListElement<T>* cur = head;
;
const ListElement<T>* forward = head->Next();


while(cur)
{
    while(forward)
    {

        if(cur->Datum() > forward->Datum())
        {

          temp = cur->Datum();
          cur->Datum() = forward->Datum();
          forward->Datum() = temp;
        }
    }
}

}

template <class T>
void LinkedList<T>::Prepend (T const& item)
{
ListElement<T>* const tmp = new ListElement<T> (item, head);
if (head == 0)
tail = tmp;
head = tmp;
}



template <class T>
void LinkedList<T>::Append (T const& item)
{
ListElement<T>* const tmp = new ListElement<T> (item, 0);
if (head == 0)
head = tmp;
else
tail->next = tmp;
tail = tmp;
}



template <class T>
LinkedList<T>::LinkedList (LinkedList<T> const& linkedList) :
head (0),
tail (0)
{
ListElement<T> const* ptr;
for (ptr = linkedList.head; ptr != 0; ptr = ptr->next)
Append (ptr->datum);
}

template <class T>
LinkedList<T>& LinkedList<T>::operator = (
LinkedList<T> const& linkedList)
{
if (&linkedList != this)
{
Purge ();
ListElement<T> const* ptr;
for (ptr = linkedList.head; ptr != 0; ptr = ptr->next)
    Append (ptr->datum);
}
return *this;
}



template <class T>
void LinkedList<T>::Extract (T const& item)
{
ListElement<T>* ptr = head;
ListElement<T>* prevPtr = 0;
while (ptr != 0 && ptr->datum != item)
{
prevPtr = ptr;
ptr = ptr->next;
}
if (ptr == 0)

    throw std::invalid_argument ("item not found");

if (ptr == head)
head = ptr->next;
else
prevPtr->next = ptr->next;
if (ptr == tail)
tail = prevPtr;
delete ptr;
}




template <class T>
void LinkedList<T>::InsertAfter (
ListElement<T> const* arg, T const& item)
{
ListElement<T>* ptr = const_cast<ListElement<T>*> (arg);
if (ptr == 0)
{

}
throw std::invalid_argument ("invalid position");
ListElement<T>* tmp = new ListElement<T> (item, ptr->next);
ptr->next = tmp;
if (tail == ptr)
{

}
tail = tmp;
}

template <class T>
void LinkedList<T>::InsertBefore (
ListElement<T> const* arg, T const& item)
{
ListElement<T>* ptr = const_cast<ListElement<T>*> (arg);
if (ptr == 0)
{

}
throw std::invalid_argument ("invalid position");
ListElement<T>* const tmp = new ListElement<T> (item, ptr);
if (head == ptr)
{

}
head = tmp;
else
{
ListElement<T>* prevPtr = head;
while (prevPtr != 0 && prevPtr->next != ptr)
    prevPtr = prevPtr->next;
if (prevPtr == 0)
{

}
throw std::invalid_argument ("invalid position");
prevPtr->next = tmp;
}
}

Ответы [ 2 ]

0 голосов
/ 03 ноября 2010

... кроме того, вы пишете, что Datum () возвращает константную ссылку, но затем вы используете вызов Datum () в качестве l-значения в "cur->Datum() = forward->Datum();".Как это назначение будет работать, когда вещь слева неизменна?

Кроме того, вы объявляете forward как указатель на константу ListElement, а затем используете forward на LHS присвоения: "forward->Datum() = temp;",Вы, вероятно, на самом деле всегда хотите вперед == cur-> Next () в два while () s.(Т.е. всегда обновляется, чтобы указывать на то, что будет дальше.) Так что это не может быть константой.

Вам действительно придется переосмыслить использование const, учитывая количество изменчивости, которое вы хотите использовать.

0 голосов
/ 03 ноября 2010

Сортировка списка - неконстантная операция; Вы не можете сделать это только с const accessors. Обычное решение состоит в том, чтобы перегрузить методы доступа константным и неконстантным вариантами:

ListElement const* Next() const { return next; }
ListElement* Next() { return next; }

Вы сделали бы то же самое для функций доступа в вашем классе LinkedList (конечно, если вы не хотите сделать список неизменным).

...