【问题标题】:Bubble sort a linklist template冒泡排序链表模板
【发布时间】:2010-11-03 04:58:45
【问题描述】:

我正在尝试对链表进行排序。我在使用 const 时遇到问题。它不会让我分配给它应该做的 const 变量。但是,我不知道如何解决这个问题? 如果能得到任何帮助,我将不胜感激。

这都是一个头文件,排序功能也是,我尽量把它拉出来好找:

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' : 你不能分配给一个 const 的变量 在编译类模板成员函数'void LinkedList::BubleSort(void)' 请参阅正在编译的类模板实例化“LinkedList”的参考

当然,如果它的 const 我不能这样做,我只是不知道如何解决这个问题。

这是所有信息所在的头文件和排序功能:

#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;
}
}

【问题讨论】:

    标签: visual-c++ data-structures bubble-sort


    【解决方案1】:

    对列表进行排序是非常量的操作;你不能只使用 const 访问器来做到这一点。通常的解决方案是使用 const 和非常量变体重载访问器:

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

    您可以对 LinkedList 类中的访问器函数执行相同的操作(当然,除非您想让列表不可变)。

    【讨论】:

    • 谢谢。我按照你说的做了,我也把它应用到了基准上。现在可以使用了。
    【解决方案2】:

    ...另外,您编写 Datum() 返回一个 const 引用,但随后您使用 Datum() 调用作为“cur-&gt;Datum() = forward-&gt;Datum();”中的左值。当左边的东西是不可变的时,这个赋值将如何工作?

    此外,您将 forward 声明为指向常量 ListElement 的指针,然后在赋值的 LHS 上使用 forward:“forward-&gt;Datum() = temp;”。您可能实际上总是希望在两个 while() 中使用 forward == cur->Next()。 (即总是更新以指向下一个。)所以它不能是 const。

    鉴于您似乎想要使用的可变性数量,您真的必须重新考虑您对 const 的使用。

    【讨论】:

    • 我知道我做错了。我只需要一些代码来显示以及我认为应该如何完成。不确定“您实际上可能总是希望在两个 while() 中向前 == cur->Next()”是什么意思。 ??????
    • @icelated:正如所写,forward 总是指向列表中的第二个项目(假设该项目存在)。由于您永远不会导致 cur 或 forward 在列表中前进,因此很难猜测您打算如何与第二个以外的任何元素进行比较。
    • 我明白你的意思了!我解决了这个问题,我在下面应用了 Fabians 解决方案,它现在可以工作了。
    猜你喜欢
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 2015-08-20
    • 2012-09-29
    • 1970-01-01
    相关资源
    最近更新 更多