2016-02-14 192 views
0

所以,嘿,我有这个项目我有一个问题。我应该从文件中读取整数并将它们插入到列表中。有一个findSpot函数需要实现遍历链表,并且如果下一个节点的值大于被检查的值,它将返回当前的“点”。然后我们输出链接列表到一个单独的文件。C++单链接列表插入排序

这是代码。

#include <iostream> 
#include <fstream> 
using namespace std; 

class listNode { 

public: 
    int value; 
    listNode* next; 
    friend class linkedList; 

    listNode() 
     : value(0) 
     , next(NULL) 
    { 
    } 

public: 
    ~listNode(){ 

    }; 
}; 

class linkedList { 
    listNode* listHead; 

public: 
    linkedList() 
     : listHead(NULL) 
    { 
    } 

    bool isEmpty() 
    { 
     return (listHead == 0); 
    } 

    void listInsert(int data, listNode* spot) 
    { 

     listNode* newNode; 
     newNode->value = data; 
     newNode->next = NULL; 

     if (isEmpty()) { 
      listHead = newNode; 
     } 

     else { 
      newNode->next = spot->next; 
      spot->next = newNode; 
      cout << newNode; 
     } 
    } 

    /*void listDelete() 
    { 

    }*/ 

    listNode* findSpot(int data) 
    { 
     listNode* spot; 
     spot = listHead; 

     while (spot->next != 0 && spot->next->value < data) { 
      spot = spot->next; 
     } 

     return spot; 
    } 

    void printList(listNode* spot) 
    { 
     listNode* newNode = spot; 

     while (newNode != NULL) { 
      cout << "Inserting " << newNode->value << ": " 
       << "listHead-->(" << newNode->value << "," << newNode->next->value << ")-->("; 
      newNode = newNode->next; 
     } 

     cout << endl; 
    } 

    /*~linkedList() 
    { 
     listNode* temp = spot->next; 
     spot->next = spot->next->next; 
     delete temp; 

    }*/ 
}; 

int main(int argc, char* argv[]) 
{ 

    int data; 
    listNode* spot; 

    ifstream infile; 
    infile.open(argv[1]); 
    ofstream outfile(argv[2]); 

    cout << "Reading Data from the file" << endl; 

    while (infile >> data) { 
     cout << data << endl; 
    } 

    infile.close(); 

    linkedList myList; 
    infile.open(argv[1]); 

    while (infile >> data) { 
     myList.findSpot(data); 
     myList.listInsert(data, spot); 
     myList.printList(spot); 
    } 

    cout << "Printing your linked list to the output file."; 

    /*while (outfile.is_open()) 
    { 
     myList.printList(); 

    }*/ 

    infile.close(); 
    outfile.close(); 

    return 0; 
} 

我不知道问题主要在于insertList函数还是它是findSpot函数。 findSpot函数对我来说似乎是正确的,但我可能会错过一些东西。

当我运行代码时,第一次读取文件的实际情况很好。实际上插入任何东西到链接列表导致程序挂起。

+0

为什么代码中的所有空行?这使得它很难阅读。在读取文件中的任何内容之前,您应该测试链表是否实际上使用了一个小的'main'函数,该函数可以调用硬编码值插入条目,以便您(和其他人)很容易诊断。如果你的链表完全不起作用,那么担心文件阅读是没有意义的。 – PaulMcKenzie

+0

哦,对不起,我想这只是一个奇怪的个人偏好。空的空间使得我可以很容易地区分彼此的东西XD – user2444400

+0

请重新格式化并重新合适您的代码。你不想让自己的代码尽可能理解和可读吗?让别人更容易看到你做了什么,以及问题出在哪里? –

回答

0

因为这看起来像一个家庭作业,我想给你一个修复:

变化

myList.findSpot(data); 

spot = myList.findSpot(data); 

如果你仔细观察,用点,但从未分配过任何东西。

+0

谢谢我忘了在一些摆弄之后提前改回它。但现在我真的陷入困境。我似乎无法确切知道链接列表有什么问题。所有参数似乎都已正确初始化,哪些不是? – user2444400

+0

好的。我会再给你一个: newNode在这里没有初始化: istNode * newNode; newNode-> value = data; newNode-> next = NULL; –

+0

噢,你的意思是通过执行listNode * newNode = new listNode来初始化它吗? ? – user2444400

0

那么,你的程序有几个问题(格式除外)。在功能findSpot(),您可以:

listNode* spot; 
spot = listHead; 

while (spot->next != 0 && spot->next->value < data) { 
    spot = spot->next; 
} 
return spot; 

这里的问题是,你第一次调用该方法,从ListHead是空的,所以

while (spot->next 

是要失败的,因为斑空值。

我还注意到,你的代码中没有地方叫new()。在listInsert中,你需要使用new()来初始化你的newNode变量。

最后,发现点有2个条件,它可以返回NULL。如果列表为空,则它应该返回NULL,并且您希望在列表的开始处插入。如果您添加的新值大于其他值,则您也将返回NULL,并且您必须将其添加到列表的末尾。

由于这是一项家庭作业,我不想为你编写代码,但希望这有助于。

+0

因为listHead为空,函数是不是只返回Spot(目前会在listHead中?)While循环只会导致它遍历,在这种情况下不需要遍历,因为没有任何东西需要遍历?当我使用listIInsert函数时不会使用spot(它是listHead)首先插入一个新节点吗? – user2444400

+0

不,它不会返回null,它会崩溃。原因是你在while循环中检查spot-> next。如果spot为NULL,那么您试图执行NULL-> next,这是一个问题 –

+0

我不知道如何解决此问题?我的教授给我的算法非常精确。我不认为我应该用随机值初始化listHead? – user2444400

1

好的,让我们再试一次。我实际上会包含一些代码,但请尝试将此用作学习点,而不是仅仅复制粘贴。我知道你说过你在复制你的老师算法,但是他们给你的东西可能就是这个算法。这是你的工作,真正落实在工作代码,检查错误条件等。总之,在这里我们去:

对于功能findSpot:

listNode* linkedList::findSpot(int data) { 
    listNode* spot = listHead; // Initialize spot to start of list 

    if (isEmpty()) // if list is empty, return NULL 
    return NULL; 

    // now we know listHead isn't null, so look through the list and 
    // find the entry that has a value greater than the one provided 
    // return the list item BEFORE the one with the greater value 
    while (spot->next != 0 && spot->next->value < data) { 
    spot = spot->next; 
    } 

    // return the one we found; This could be the same as listHead 
    // (start of list), something in the middle, or the last item on the 
    // list. If we return from here, it will not be NULL 
    return spot; 
} 

现在我们可以插入功能:

void linkedList::listInsert(int data, listNode* spot) { 

    // We need a new item to put on the list, so create it 
    listNode* newNode = new listNode(); 
    newNode->value = data; 
    newNode->next = NULL; 

    // If the list is empty, update the head to point at our new object 
    if (isEmpty()) { 
    listHead = newNode; 

    // otherwise point spot to new item, and new item to the one spot 
    // pointed to 
    } else { 
    newNode->next = spot->next; 
    spot->next = newNode; 
    } 
} 

看看你的打印功能,这将有它自己的问题。它看起来像要打印整个列表,但似乎您开始从“spot”打印。这一切都很困惑。它也有一个问题,使用newNode-> next-> value,而不检查newNode-> next是否为NULL。这里是什么,我认为你正在尝试做的...请注意,我甚至都不需要在现场通过一个简单的例子,只是数据点补充说:

void linkedList::printList(int data) { 

    // if some huckleberry called this before calling insert, 
    // list will be empty... always a good idea to check 
    if (isEmpty()) 
    return; 

    // first line of output... just print out the data point 
    // added and start of output text 
    cout << "Inserted " << data << ": " << "listHead-->("; 

    // start at start of list 
    listNode* newNode = listHead; 

    // loop through until we find the end 
    while (newNode != NULL) { 

    cout << newNode->value;  // print the value 
    newNode = newNode->next;  // move to the next item on the list 

    // We moved to the next node; It might be NULL and the loop will end 
    // if not, we want to print an open bracket since we know another one 
    // is going to be printed 
    if (newNode != NULL) 
     cout << ")-->("; 
    } 

    // last item was just printed, so close off the last bracket 
    cout << ")" << endl; 
} 

希望这是有点用