维护按字母顺序排列的链表

时间:2016-06-07 14:26:24

标签: c++ list

我正在学习c ++并试图按字母顺序维护链表。如果我要输入一个名单“Mary,bob,sally,larry,david,roger”,我希望他们打印出来(在浏览列表之后)“bob,david,larry,mary,roger,sally”。任何帮助将不胜感激。谢谢!

注意:当我尝试执行代码时,代码不按字母顺序打印名称。道歉,我写道,但显然我没有。它编译得很好,但产生的结果并不是预期的结果。

编辑:我发现了一些有趣的东西。我尝试构建文件时遇到错误c:/mingw/bin/../lib/gcc/mingw32/4.9.3/../../../../mingw32/bin/ld.exe: cannot open output file Program18ContactList.exe: Permission denied collect2.exe:error: 1d returned 1 exit status它运行,但是当我尝试重建任何更改时,我收到了该消息。我知道这意味着什么,但我不确定如何解决它。我没有删除任何源文件。我使用的是最新版本的Eclipse Mars.2

主要

//Contact list playing with classes
//Contact lists

#include "ContactList.H"
using namespace std;


int main()
{

    ContactList* cl1 = new ContactList();

    string name;

    while(true)
    {

        cout << "Enter the name of the contact or q to quit." << endl;
        cin >> name;
        if(name == "q")
        {
            break;
        }
        cl1->insert(name);

    }

    cl1->printList();

    return(0);
}

//contact list class

#include "ContactList.H"
using namespace std;

ContactList::ContactList():head(0), size(0)
{}

void ContactList::addToHead(const string& name)
{

    Contact* newOne = new Contact(name);

    if(head == 0)
    {
        head = newOne;
    }
    else
    {
        newOne->next = head;
        head = newOne;
    }

    size++;
}

void ContactList::printList()
{

    Contact* tp = head;

    while(tp != 0)
    {

        cout << *tp << endl;
        tp = tp->next;

    }

}

void ContactList::insert(const string& name)
{

    Contact* newNode = new Contact(name);

    // case 1 - empty list
    if(head == 0)
    {
        //assigns new node to the empty list head node
        head = newNode;

    }
    else
    {
        //current pointer initialized to the head so as to start traversal
        // trail pointer initialized to zero, but will iterate one step behind
        // current to keep former data location on the stack organized
        Contact* curr = head;
        Contact* trail = 0;

        // Traverse list to find insert location
        while(curr != 0)
        {

            if(curr->name >= newNode->name)
            {
                break;
            }
            else
            {

                trail = curr;
                curr = curr->next;

            }
        }

        // case 2 - insert at head (not empty)
        if(curr == head)
        {

            newNode->next = head;
            head = newNode;
        }
        else
        {

        // case 3 - insert after the head (not empty)
        newNode->next = curr;
        trail->next = newNode;
        }

    }

    size++;
}

1 个答案:

答案 0 :(得分:1)

到目前为止,您的列表似乎工作正常。但请注意,调用addToHead会破坏排序。当然,您没有这样做,但是您提供了一个能够破坏列表的预期功能的接口(正在进行排序)。最好完全放弃它。

您最常遇到的问题是operator>=区分大小写,因此"Zebra" <\ n> 大于或等于"ant"({{ 1}})因此if(curr->name >= newNode->name) break;将被排在"ant"之后,因为ascii'Z'(90)小于ascii'a'(97)。

您可以提供我们自己的运算符(必须至少在"Zebra"定义之前声明):

insert

这很有用,幸运的是,std :: string的运算符实际上是模板,因此该运算符在重载决策中具有优先权。

只是旁注:这绝对适用于ascii,如果使用单字节编码,适用于大多数语言。但是,有些问题与e。 G。土耳其语,如果使用utf-8,你可能会遇到问题。可能现在超出范围,但你可能记得将来......

我个人倾向于认为“Alpha”大于“alpha”,“bEta”大于“beTA”,...(与ascii代码相反!) - 但实际上,只是品味问题。不过,您可以通过将bool operator>=(std::string const& x, std::string const& y) { std::string::iterator ix = x.begin(); std::string::iterator iy = y.begin(); while(ix != x.end() && iy != y.end()) { if(toupper(*ix) > toupper(*iy)) return true; if(toupper(*ix) < toupper(*iy)) return false; } // both strings are equal so far... // at least one string is at its end // // if iy is, then y is not longer than x and thus // lexicographically not larger than x (so x is larger or equal) return iy == y.end(); } 替换为:

来强制执行此类排序
return iy == y.end();