【问题标题】:C++ - How to sort data in a linked list and display it?C++ - 如何对链表中的数据进行排序并显示?
【发布时间】:2018-05-07 02:34:16
【问题描述】:

我目前正在开发一个具有链接列表的程序。我的程序需要一个函数,可以根据月份对所有数据进行排序,然后显示所有数据,但我找不到一个很好的例子供我参考,因为在我的情况下,我需要搜索 string expireDate; 哪个以这种方式输入dd/mm/yyyy,这意味着我需要使用std::string str2 = temp->expireDate.substr(3,2); 获取它的子字符串,以便我获取月份,然后使用int month; 将子字符串转换为整数。请看一下我的代码,它是排序的,但我运行它时没有显示任何内容,我认为一定有一个很小的错误。我已经发现了自己的错误,实际上这只是一个愚蠢的错误。这段代码没有错误。

carInsurance* remove_next(carInsurance* prev)// pass NULL if start_ptr is the Node to be removed
{
    if(prev)
    {
        if( prev->next )// ensure prev isn't pointing to the last Node in the list
        {
            carInsurance* temp = prev->next;// temp will be removed
            prev->next = temp->next;// link across temp
            return temp;
        }
    }
    else if(start_ptr)// ensure list not empty
    {
        carInsurance* temp = start_ptr;// start_ptr will be removed
        start_ptr = start_ptr->next;
        return temp;
    }

    return NULL;// if called on empty list, or if prev->next is NULL
}

void carInsurance::sortMonth(int *x) // sort by month in ascending order
{
    carInsurance *start_ptr2 = NULL;// head of sorted list
    float price, addPrice;

    while(start_ptr)// repeat until no nodes left in unsorted list
    {
        // pointers for iterating through the unsorted list
        carInsurance *prev = NULL;// always previous to the current node considered (below)
        carInsurance *curr = start_ptr;// start at beginning of list
        carInsurance *prevMax = NULL;// pointer to node before the node with the highest age
        int max = start_ptr->month;// 1st node holds max age to start

        while(curr)// iterate through the list
        {
            if(curr->month > max )// new highest age found
            {
                max = curr->month;// save new max age
                prevMax = prev;// save pointer to node before the max
            }
            prev = curr;// advance iterators
            curr = curr->next;
        }

        // Node with the highest age found this pass through the list.
        carInsurance *xferNode = remove_next(prevMax);// obtain node to be moved into sorted list
        if( xferNode )// check that it's not NULL
        {
            xferNode->next = start_ptr2;// add to beginning of sorted list
            start_ptr2 = xferNode;
        }
    }
    start_ptr = start_ptr2;// list now sorted. Reassign start_ptr to point to it.

    while(temp != NULL)// Display details for what temp points to
    {
        cout << "\n___Customer Information___\n" << endl;
        cout << "\nName : " << temp->name << endl;
        cout << "IC: "<< temp->iCno << endl;
        cout << "Date of Birth: " << temp->dob << endl;
        cout << "Nationality: " << temp->nationality << endl;
        cout << "Address: " << temp->address << endl;
        cout << "Mobile Number: " << temp->phoneNo << endl;
        cout << "Email: " << temp->email << endl;
        cout << "Occupation: " << temp->occupation << endl;

        cout << "\n_____Car Information_____\n" << endl;
        cout << "Car Plate Number: " << temp->carNo << endl;
        cout << "Insurance Expire Date: " << temp->expireDate << endl;
        cout << "Usage of Car Model/Make: " << temp->carUsage << endl;
        cout << "Manufacturing Date: " << temp->manufacturingDate << endl;

        cout << "\n___Insurance Information___\n" << endl;
        cout << "Insurance Package:" << endl;
        if(temp->package == 1)
        {
            cout << "\nPackage A (Comprehensive Cover)" << endl;
            cout << "\t-Covers losses or damages to your car due to accident, fire and theft    " << endl;
            cout << "\t-Covers Third Party death and bodily injuries                            " << endl;
            cout << "\t-Covers Third Party property losses or damages                           " << endl;
            price = 1000;

        }
        else if (temp->package == 2)
        {
            cout << "\nPackage B (Third Party Cover)" << endl;
            cout << "\t-Covers Third Party death and bodily injuries" << endl;
            cout << "\t-Covers Third Party property losses or damages" << endl;
            price = 1500;
        }
        else if (temp->package == 3)
        {
            cout << "\nPackage C (Third Party, Fire & Theft Cover)" << endl;
            cout << "\t-Covers losses or damages to your car due to fire or theft" << endl;
            cout << "\t-Covers Third Party death and bodily injuries" << endl;
            cout << "\t-Covers Third Party property losses or damages" << endl;
            price = 900;
        }
        else
        cout << "No package available" << endl;

        if(temp->additional == 1)
        {
            cout << "\nAdditional package: "<< endl;
            if (temp->option==1){
                cout << "Road tax renewal" << endl;
                addPrice = 50;
            }

            else if (temp->option==2){
                cout << "Name of second driver" << endl;
                addPrice = 0;
            }

            else if (temp->option==3){
                cout << "Windscreen coverage" << endl;
                addPrice = 20;
            }

            else if (temp->option==4){
                cout << "Rental reimbursement" << endl;
                addPrice = 50;
            }

            else if (temp->option==5){
                cout << "Roadside assistance or towing insurance" << endl;
                addPrice = 80;
            }

            else if (temp->option==6){
                cout << "Full glass coverage" << endl;
                addPrice = 70;
            }
            else
                cout << "Not availabe"<< endl;
            }
            else{
                cout << "No additional package" << endl;
                price = 0;
            }
            temp->insuranceAmount = price + addPrice;
            cout << "Amount to be insured: RM" << temp->insuranceAmount << endl;

            //temp = temp->next;
            }//End of While Loop
}//End of sortMonth

【问题讨论】:

  • 显示的代码中似乎没有任何与排序相关的内容;相反,它看起来像是十二个几乎相同的代码块的开始。我想你会发现一些有用的信息可能会对你有所帮助at this link
  • 问:这对我来说是正确的排序方式吗?答:呃,没有。建议:考虑将您的数据放入 C++ vector,并尝试使用 std::sort()。这是一个例子:Beginners guide to the std::sort() function

标签: c++ class sorting linked-list


【解决方案1】:

您是否允许使用所有 C++ 或者您真的只允许将 C 与 std::string 和 std::cout 一起使用?

如果你可以在这里使用 C++,我会这样做(仍然使用链表,因为你在问题中指定了它 - 如果你不需要使用 std::vector 和 std::sort 会更高效一个链表):

#include <iostream>
#include <sstream>
#include <iterator>
#include <locale>
#include <vector>
#include <list>

// define a facet that adds slash to the list of delimiters
class slash_is_space : public std::ctype<char> {
public:
    mask const *get_table() { 
        static std::vector<std::ctype<char>::mask> 
            table(classic_table(), classic_table()+table_size);
        table['/'] = (mask)space;
        return &table[0];
    }
    slash_is_space(size_t refs=0) : std::ctype<char>(get_table(), false, refs) { }
};

// define a class (with public members) that adds splits the date using the new facet
struct extract_date
{
    int day, month, year;
    extract_date(std::string date) {
        std::stringstream ss(date);
        ss.imbue(std::locale(std::locale(), new slash_is_space));
        ss >> day >> month >> year;
    }
};

// your struct containing the date that will be used for sorting
struct carInsurance
{
    std::string carNo;
    std::string expireDate;
    std::string carUsage;
    std::string manufacturingDate;
};

// a function that can print your struct
std::ostream& operator << ( std::ostream& out, const carInsurance& rhs )
{
    out << rhs.carNo      << ", "
        << rhs.expireDate << ", "
        << rhs.carUsage   << ", "
        << rhs.manufacturingDate;
    return out;
}

int main()
{
    // your linked list of data
    std::list<carInsurance> cars{{"a","00/01/0000","a","a"},
                                 {"b","00/03/0000","b","b"},
                                 {"c","00/02/0000","c","c"}};

    // sort the list by expireDate month
    cars.sort([](carInsurance& a, carInsurance& b){
        extract_date a_date(a.expireDate);
        extract_date b_date(b.expireDate);
        return a_date.month < b_date.month;
    });

    // print the sorted list
    std::copy(cars.begin(), cars.end(), std::ostream_iterator<carInsurance>(std::cout, "\n"));

    return 0;
}

【讨论】:

  • 如果我使用这种方法,我是否也需要改变我在链表中​​输入所有数据的方式?如果你想看看我的full code click this
  • 我也对struct carInsurance 和我的class carInsurance 感到困惑,因为我正在使用一个类来制作这个链接列表
  • @beginner struct { blah }class { public: blah } 相同,class { blah } 实际上只是 class { private: blah },因此 struct 默认情况下会公开所有成员。我这样做是为了使代码更短,但在真正的程序中你可能会有访问器。
  • @beginner 如果是家庭作业,那么您可以使用 std::list 还是必须制作自己的链表?如果这不是家庭作业,您可能需要考虑是否需要链表或向量是否更好。
  • @beginner 我将添加一些输入链接列表数据的内容,而不是对其进行硬编码。
猜你喜欢
  • 2015-07-14
  • 2017-12-31
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 2012-10-07
  • 1970-01-01
相关资源
最近更新 更多