在双向链表中插入排序

时间:2014-09-27 17:10:12

标签: c++ doubly-linked-list insertion-sort

我从头开始用C ++制作一个列表,而不是使用STL列表功能。我的程序是为用户设计的,一次一个地向列表中插入一个新项目(字符串)。这些项目应该在插入时进行排序,并且部分有效。用户应该能够向前和向后打印它们。

示例:

  • 我插入:1,3,2 - 结果向前:1,2,3 - 向后:3,2,1
  • 我插入1,3,2,4 - 结果向前:1,4,2,3 - 向后:3,2,4,1
  • 我插入4,2,3 - 结果向前:2,3,4 - 向后:4,3,2
  • 我插入4,2,3,1 - 结果转发:1,4 - 向后:1,3重复,直到程序崩溃

这些是一些例子,我可以包括更多。我不能为我的生活看到我的代码出了什么问题。我从那些我认识的人那里得到了很好的帮助,但他们看了几个小时之后就找不到了问题。我已经被困在这几天了,我只是没有看到它。

这是我的代码(评论是挪威语,对不起!):

的main.cpp

#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

//definerer noden
struct node
{
    string data;    //det noden inneholder
    node* next;     //nestepeker
    node* prev;     //forrigepeker
};

//definerer funksjonene
bool isEmpty(node* first);
char menu();
void insertAsFirstElement(node* &first, node* &end, string data);
void insert(node* &first, node* &end, string data);
void remove(node* &first, node* &end, string data);
void showList(node* first);
void printBackwards(node* end);


//er noden tom?
bool isEmpty(node* first)
{
    if(first == NULL)
        return true;
    else
        return false;
}


//sender valgskjermen til konsollen
char menu()
{
    char choice;

    cout << "Welcome to LISTOMANIA 3000x! \n" << endl;
    cout << "Press <1> to add an item" << endl;
    cout << "Press <2> to remove item on top" << endl;
    cout << "Press <3> to display the list forward" << endl;
    cout << "Press <4> to display the list backwards" << endl;
    cout << "Press <5> to exit" << endl;
    cout << "\nInput: ";

    cin >> choice;

    return choice;
}


//hvis lista er tom, sett inn node som første element:
void insertAsFirstElement(node* &first, node* &end, string data)
{
    cout << "temp is first\n";
    node* temp = new node;
    temp->data = data;
    temp->next = NULL;
    temp->prev = NULL;
    first = temp;
    end = temp;
}


//hvis lista ikke er tom, sett inn noden sortert:
void insert(node* &first, node* &end, string data)
{
    if(isEmpty(first))
    {
        insertAsFirstElement(first, end, data);
    }
    else
    {
        node* temp = new node;
        temp->data = data;
        node* n = first;

       while(n)
       {
            if(n->data > temp->data)
            {

                cout << "temp BEFORE n" << endl;
                temp->prev = n->prev;
                temp->next = n;
                n->prev = temp;

                if(temp->prev)
                {
                    temp->prev->next = temp;
                }
                else
                {
                    first = temp;
                }
            }
            else if(n->data <= temp->data)
            {
                cout << "temp AFTER n" << endl;
                //temp = new node;
                //temp->data = data;
                temp->prev = n;
                temp->next = n->next;
                n->next = temp;

                if(temp->next)
                {
                    temp->next->prev = temp;
                }
                else
                {
                    end = temp;
                }
                break;
            }

            n = n->next;
        }
    }
}


//sletter valgt node
void remove(node* &first, node* &end, string data)
{
    string delItem;
    node* temp;    

    if(isEmpty(first))
        cout << "\nNothing to delete, the list is empty!\n------------------------------------------------\n------------------------------------------------\n";
    else if(first == end)
    {
        cout << "\nYou removed <" << first->data << ">!" << endl;
        delete first;
        first = NULL;
        end = NULL;
        cout <<"------------------------------------------------\n------------------------------------------------\n";
    }
    else
    {
        node* temp = first;
        cout << "You removed <" << temp->data << ">!" << endl;
        first = first->next;
        delete temp;
        cout <<"------------------------------------------------\n------------------------------------------------\n";

    }
}


//skriver ut listen alfabetisk
void showList(node* first)
{
    node * temp = first;

    if(isEmpty(first))
    {
        cout << "\nThe list is empty!\n";
    }
    else
    {
        cout << "\nThe list contains: \n\n";
        while(temp != NULL)
        {
            cout << temp->data << endl;
            temp = temp->next;
        }
    }

    cout << "------------------------------------------------\n";
    cout << "------------------------------------------------\n";
}


//skriver ut listen omvendt alfabetisk
void printBackwards(node* end)
{
    node * temp = end;

    if(isEmpty(end))
    {
        cout << "\nThe list is empty!\n";
    }
    else
    {
        cout << "\nThe list contains: \n\n";
        while(temp != NULL)
        {
            cout << temp->data << endl;
            temp = temp->prev;
        }
    }

    cout << "------------------------------------------------\n";
    cout << "------------------------------------------------\n";
}


//mainfunksjon
int main()
{
    node* first = NULL;
    node* end = NULL;
    char choice;
    string data;

    do
    {
        choice = menu();

        switch(choice)
        {
            case '1':   cout <<"\nPlease add something to the list: ";
                        cin >> data;
                        insert(first, end, data);
                        cout << "------------------------------------------------\n------------------------------------------------\n";
                        break;
            case '2':   remove(first, end, data);
                        break;
            case '3':   showList(first);
                        break;
            case '4':   printBackwards(end);
                        break;
            case '5':   cout << "\nSystem exit...\n";
                        break;
            default: cout << "\nInvalid input!\n------------------------------------------------\n------------------------------------------------\n";
        }
    }while(choice != '5');

    return 0;
}

只需忽略连字符的行,它们只是让程序在运行时看起来更漂亮。

请注意我是初学者!除了我的问题,可能还有很多其他错误。同样忽略remove函数,因为我还没有解决这个问题......

2 个答案:

答案 0 :(得分:0)

检查我添加了评论//1.this line//2.this line的两行,然后在temp<n时调用第一行,因此您必须将temp与之前的{{1}节点进行比较第二个用于n,因此您需要将temp>=ntemp的下一个节点进行比较。到目前为止我所说的很明显,你必须删除我用n注释的行,这是导致你最后一个问题的原因。另外你还有另一个错误,你必须删除//4.you should remove this line : n = temp->next;它在排序中间留下你的列表,这样你的排序就永远不会完成,这就是造成另一个问题的原因。

break;

答案 1 :(得分:0)

我得到了更多人的帮助,我们找到了解决方案。这是我的insert功能:

//hvis lista ikke er tom, sett inn noden sortert:
void insert(node* &first, node* &end, string data)
{
    if(isEmpty(first))
    {
        insertAsFirstElement(first, end, data);
    }
    else
    {
        node* temp = new node;
        temp->data = data;
        temp->next = first;
        temp->prev = NULL;
        first->prev = temp;
        first = temp;
    }

    //sortering
    if(first != NULL)
    {
        node* current = first;
        node* prev = NULL;
        node* tempNode = NULL;


        while(current->next != NULL)
        {
           tempNode = current->next;

           //cout << "current: " << current->data << " tempNode: " << tempNode->data << endl;

           if(current->data > tempNode->data)
           {
               //cout << "swapped " << "current: " << current->data << " tempNode: " << tempNode->data << endl;
               swap(current->data, tempNode->data);
           }
           else
           {
               prev = current;
               current = current->next;
           }
        }
    }
}

如果数据为string,则对数据进行排序,数字上有一点错误,解释为string,可以通过将所有数字转换为int来解决。< / p>

编辑: 与nubmers的错误根本不是一个错误。该列表认为11小于5,但这是因为每个输入都被视为string。那么如果你认为1 = a和2 = b,那么11&lt; 11&lt; 11&lt; 11因此,如果你想要对它们进行分类,那么它将在逻辑上如何完成,11> 5,您必须将所有数字转换为int