带链接列表的插入排序

时间:2018-10-28 19:10:46

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

我一直在尝试使用插入列表进行插入排序。我花了最后三天的时间在算法上,甚至尝试联系了4位没有帮助的老师。当我运行该程序时,它将从一个.csv文件读取,打印,然后对列表进行排序,然后再次打印。由于程序崩溃,排序本身存在问题。我仅使用链表一个星期,对于任何导致问题的原因,我们将不胜感激。

#include "pch.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

using namespace std;

// struct containing node data
struct node {
    string firstName;
    string lastName;
    string country;
    string phone;
    double contribution;
    int id;
    node * next;
};

// list class
class list {
private:
    node *head, *tail;
public:
    list() {
        head = nullptr;
        tail = nullptr;
    }

    // CREATE node with arguments taken from input file
    void createNode(string FirstName, string LastName, string Country, string Phone, double Contribution, int ID) {
        node *temp = new node;                  // create empty node
        temp->firstName = FirstName;
        temp->lastName = LastName;
        temp->country = Country;
        temp->phone = Phone;
        temp->contribution = Contribution;
        temp->id = ID;
        temp->next = nullptr;

        if (head == nullptr) {                  // if first node
            head = temp;
            tail = temp;
            temp = nullptr;
        }
        else {
            tail->next = temp;
            tail = temp;
        }
    }

    // PRINT
    void print() {
        node *temp = new node;                  // create empty node
        temp = head;
        // until end of list
        while (temp != nullptr) {
            cout << temp->lastName << ", " << temp->firstName << '\t'
                << temp->country << '\t' << temp->phone << '\t'
                << temp->contribution << '\t' << temp->id << endl;
            temp = temp->next;
        }
    }

    void insertionSort()
    {

        node *sortNode = new node;  // EMPTY NODE to sort into
        node *temp = new node;      // temp node is to traverse
        temp = head;            // set traversal node

        while (temp != nullptr) {
            node *nextNode = temp->next;

            // sort
            node *current = new node;
            if(sortNode == nullptr || strcmp(temp->firstName.c_str(), nextNode->firstName.c_str()) > 0) {
                temp->next = sortNode;
                sortNode = temp;

            }
            else {

                current = sortNode;
                while ((current->next != nullptr) && strcmp(current->next->firstName.c_str(), temp->firstName.c_str()) > 0)
                {
                    current = current->next;
                }
                temp->next = current->next;
                current->next = temp;
            }
            temp = nextNode;    // go to next node

        }
        head = sortNode;       
    }




    void pop() {
        node *curr = new node;
        node *previous = new node;
        curr = head;
        // find end of node
        while (curr->next != nullptr) {
            previous = curr;
            curr = curr->next;
        }
        previous->next = curr->next;
    }



};

int main()
{
    string firstName;
    string lastName;
    string country;
    string phone;
    double contribution;
    int id;
    string temp;    // store int/double as string, convert

    string line;

    list List;

    ifstream inFile("contributors.csv");
    if (!inFile) {
        cerr << "File failed to open.\n";
    }

    // read data from file by line
    while (getline(inFile, line)) {
        stringstream ss(line);                  // parse line
        getline(ss, firstName, ',');
        getline(ss, lastName, ',');
        getline(ss, country, ',');
        getline(ss, phone, ',');
        getline(ss, temp, ',');
        contribution = stod(temp);
        getline(ss, temp, ',');
        id = stoi(temp);

        // create a node
        List.createNode(firstName, lastName, country, phone, contribution, id);
    }

    List.print();
    cout << endl;
    List.insertionSort();
    cout << endl;
    List.print();


}

.csv文件以供参考-https://pastebin.com/p9VTazC8

1 个答案:

答案 0 :(得分:0)

node *temp = new node;                  // create empty node
temp = head;

与问题无关,但是您正在为新的指针temp分配内存,然后为temp分配了另一个指针。除了内存泄漏之外,这什么都没有实现。更改为:

node *temp = head;

在功能insertionSort中,您拥有

if(sortNode == nullptr || strcmp(temp->firstName.c_str(), nextNode->firstName.c_str()) > 0)

您无需检查nextNode是否为nullptr。有时在某些情况下nextNodeNULL,然后您尝试访问nextNode.firstName。这就是程序崩溃的原因。

您必须学习调试程序。在Visual Studio中,单击“调试”按钮。程序崩溃时,转到“堆栈窗口”(Control + Alt + C),这将向您显示代码中令人反感的行。

第二,您已经有一个列表,然后基本上您尝试插入到新列表中。您应该添加一个新功能来插入在第一次运行中排序的内容:

struct node 
{
    node() 
    { 
        next = nullptr; 
    }

    node(const string& fn, const string& ln, const string& cn, const string& ph, 
        double contrib, int i)
    {
        next = nullptr;
        firstName = fn;
        lastName = ln;
        country = cn;
        phone = ph;
        contribution = contrib;
        id = i;
    }

    string firstName;
    string lastName;
    string country;
    string phone;
    double contribution;
    int id;
    node *next;

    friend ostream& operator<<(ostream& os, const node& n)
    {
        os  << n.lastName << ", " << n.firstName << '\t' << n.country << '\t' 
            << n.phone << '\t' << n.contribution << '\t' << n.id << endl;
        return os;
    }
};

class list 
{
private:
    node *head, *tail;
public:
    list() 
    {
        head = nullptr;
        tail = nullptr;
    }

    void append(const string& fn, const string& ln, const string& cn, 
        const string& ph, double contrib, int i)
    {
        node *ptr = new node(fn, ln, cn, ph, contrib, i);
        if(head == nullptr)
        {
            head = ptr;
            tail = ptr;
        }
        else
        {
            tail->next = ptr;
            tail = ptr;
        }
    }

    void insert_sorted(const string& fn, const string& ln, const string& cn, 
        const string& ph, double contrib, int i)
    {
        node *ptr = new node(fn, ln, cn, ph, contrib, i);

        if(head == nullptr)
        {
            head = ptr;
            tail = ptr;
        }
        else
        {
            bool inserted = false;
            node *walk = head;
            node *prev = nullptr;
            while(walk)
            {
                if(ptr->firstName < walk->firstName)
                {
                    //2 cases, inserting at the start or middle
                    if(walk == head)
                    {
                        //start
                        ptr->next = head;
                        head = ptr;
                    }
                    else
                    {
                        //middle
                        prev->next = ptr;
                        ptr->next = walk;
                    }

                    inserted = true;
                    break;
                }
                prev = walk;
                walk = walk->next;
            }

            if(!inserted)
            {
                tail->next = ptr;
                tail = ptr;
            }
        }
    }

    void print() 
    {
        node *ptr = head;
        while(ptr) 
        {
            cout << *ptr;
            ptr = ptr->next;
        }
    }
};

int main()
{
    string firstName;
    string lastName;
    string country;
    string phone;
    double contribution;
    int id;
    string temp;    
    string line;
    list List;
    ifstream inFile("contributors.csv");
    if(!inFile) 
        cerr << "File failed to open.\n";

    // read data from file by line
    while(getline(inFile, line)) 
    {
        stringstream ss(line);                  // parse line
        getline(ss, firstName, ',');
        getline(ss, lastName, ',');
        getline(ss, country, ',');
        getline(ss, phone, ',');
        getline(ss, temp, ',');
        contribution = stod(temp);
        getline(ss, temp, ',');
        id = stoi(temp);

        //List.append(firstName, lastName, country, phone, contribution, id);
        List.insert_sorted(firstName, lastName, country, phone, contribution, id);
    }

    List.print();

    return 0;
}

或者,您可以使用createNode创建未排序的列表,然后使用排序功能对列表进行排序。

要以其他方式执行此操作,请创建一个新列表temp_list,然后插入已排序的temp_list.insert_sorted(...),然后从List复制temp_listList中删除项目(但这不是很有效)