我一直在尝试使用插入列表进行插入排序。我花了最后三天的时间在算法上,甚至尝试联系了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
答案 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
。有时在某些情况下nextNode
是NULL
,然后您尝试访问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_list
到List
中删除项目(但这不是很有效)