2014-12-10 3 views
0

내 프로그램은 여러 함수를 실행하기위한 것이고 insertnode는 사용자로부터 값을 가져 와서 노드를 사용하여 노드의 목록을 생성하고 최소에서 최대까지 순서대로 정렬하며, printlist는 값을 구분하여 인쇄합니다 공백으로, mergelist 순서대로 두 목록을 병합하고 reverseelist 목록을 되돌립니다. 명령 프롬프트는 값을 허용하지만 두 번째 목록에 대해 중지 조건 (0)을 입력하면 충돌합니다. Visual Studio에는 오류가 표시되지 않습니다. 함수 나 포인터에 문제가있는 것 같습니다. 누군가 나에게 메모리 누출에 대해 이야기했지만 Im은 그것을 고칠 방법을 확신하지 못했습니다.사용자로부터 값을받은 후 프로그램이 충돌 함

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

class node { 
private: 
    double num; 
    node *link; 
public: 
    node() { } 
    node(double m, node *n) { num = m; link = n; } 
    node* getlink() { return link; } 
    double getdata() { return num; } 
    void setdata(double m) { num = m; } 
    void setlink(node* n) { link = n; } 
}; 

typedef node* nodeptr; 

void insertnode(nodeptr& head, double m); 
void printlist(nodeptr head); 
nodeptr mergelists(nodeptr& head1, nodeptr& head2); 
void reverselist(nodeptr& head); 

int main() 
{ 
    double input;a 
    nodeptr head1 = NULL;  // Pointer to the head of List #1 
    nodeptr head2 = NULL;  // Pointer to the head of List #2 

    nodeptr temp; 

    // Part 1 - Create two sorted lists 

    cout << "-------------------------------------" << endl; 
    cout << "CREATE LIST #1: " << endl; 
    cout << "-------------------------------------" << endl; 
    do { 
     cout << "Enter value (0 to quit): "; 
     cin >> input; 

     insertnode(head1, input); 

    } while (input != 0); 

    cout << "-------------------------------------" << endl; 
    cout << "CREATE LIST #2: " << endl; 
    cout << "-------------------------------------" << endl; 
    do { 
     cout << "Enter value (0 to quit): "; 
     cin >> input; 

     insertnode(head2, input); 

    } while (input != 0); 

    // Part 1 - Print the lists to make sure that they are correct. 
    printlist(head1); 
    printlist(head2); 
    // Part 2 - Merge the two lists and display the new merged list 
    temp = mergelists(head1, head2); 
    printlist(temp); 
    // Part 3 - Reverse the merged list and then display it 
    reverselist(temp); 
    printlist(temp); 


    return 0; 
} 

void insertnode(nodeptr& head, double m){ 
    nodeptr p = head; 
    nodeptr k = p; 
    if (!p){ 
     nodeptr n = new node(m, NULL); 
    } 
    else { 
     while (m >= p->getdata()){ 
      k = p; 
      p = p->getlink(); 
     } 
     nodeptr n = new node; 
     n->setdata(m); 
     k->setlink(n); 
     if (p){ 
      n->setlink(p); 
     } 

    } 

} 

void printlist(nodeptr head){ 
    nodeptr p = head; 
    while (p){ 
     double m = p->getdata(); 
     cout << m << " "; 
     p = p->getlink(); 
    } 
    cout << endl; 
} 

nodeptr mergelists(nodeptr &head1, nodeptr &head2){ 
    nodeptr result = 0, last = 0;; 
    if (head1->getdata() <= head2->getdata()){ 
     result = head1; 
     head1 = head1->getlink(); 
    } 
    else { 
     result = head2; 
     head2 = head2->getlink(); 
    } 
    last = result; 
    while (head1 && head2){ 
     if (head1->getdata() <= head2->getdata()){ 
      last->setlink(head1); 
      last = head1; 
      head1 = head1->getlink(); 
     } 
     else{ 
      last->setlink(head2); 
      last = head2; 
      head2 = head2->getlink(); 
     } 
    } 
    if (head1) 
     last->setlink(head1); 
    else if (head2) 
     last->setlink(head2); 
    last = 0; 
    head1 = 0; 
    head2 = 0; 
    return result; 
} 

void reverselist(nodeptr& head){ 
    stack<double> holder; 
    nodeptr p = head; 
    while (p){ 
     holder.push(p->getdata()); 
     p = p->getlink(); 
    } 
    p = head; 
    while (p){ 
     p->setdata(holder.top()); 
     holder.pop(); 
     p = p->getlink(); 
    } 
} 
+0

'이중 입력; a' 그곳에서 무엇을하고 있습니까? 또한 프로그램을 디버깅 한 경우 새 노드를 할당하는 것 외에는 아무것도 입력하지 않는다는 것을 알 수 있습니다. 연결된 목록이 만들어지지 않습니다. 당신의'insertnode' 함수는'head1'을 갱신하지 않습니다. – PaulMcKenzie

+0

@ PaulMcKenzie 이중 입력 : 복사 할 코드를 선택할 때 오류가 발생했습니다. 게시하기 전에는 그 오류가있었습니다. 하지만 디버깅에는 경험이 없으며 결코 해보지 않았습니다. insertnode 함수를 어떻게 수정합니까? –

+0

'그러나 나는 디버깅에 경험이 없으며 한번도 해본 적이 없다. '당신이 작성한 모든 프로그램이 처음으로 작동 할 것이라고 기대 했습니까? 그리고 그것이 효과가 없을 때, 당신은 무엇을 할 것입니까? 디버깅은 프로그램을 작성하는 방법을 배우는 과정의 일부분이며 필요한 단계는 아니며 의무적입니다. – PaulMcKenzie

답변

1

이 방법으로 몇 가지 문제가 있습니다

void insertnode(nodeptr& head, double m){ 
    nodeptr p = head; 
    nodeptr k = p; 

    if (!p) 
    { 
     head = new node(m, NULL); // Update head 
    } 
    else 
    { 
     while (p && m >= p->getdata()) // Check for p!=NULL 
     { 
      k = p; 
      p = p->getlink(); 
     } 
     nodeptr n = new node; 
     n->setdata(m); 
     k->setlink(n); 
     if (p) 
     { 
      n->setlink(p); 
     } 
    } 
} 

단순화 된 버전 :

void insertnode(nodeptr& head, double m) 
{ 
    nodeptr p = head; 
    nodeptr k = nullptr; 

    while (p && m >= p->getdata()) 
    { 
     k = p; 
     p = p->getlink(); 
    } 

    if (!k) 
    { 
     head = new node(m, p); 
    } 
    else 
    { 
     k->setlink(new node(m, p)); 
    } 
} 
+0

변경 사항을 적용한 후 첫 번째 목록에 3 개의 값을 입력하면 프로그램이 중단됩니다. –

0

두 가지 문제가 있습니다 당신이 헤드 노드를 업데이트하지 않는 것입니다 연결된 목록에 삽입 할 때. 앞의 대답은 @uncletall에 의해 설명되었습니다.

두 번째 문제는 매우 간단합니다. node을 기본 구성 할 때 link을 NULL로 초기화하지 못했습니다. 당신의 node 클래스에서 다음과 같이 변경합니다 :

class node { 
private: 
    double num; 
    node *link; 
public: 
    node() : link(0) { } // here is the change here 
    //... 
    //... the rest of your code 
}; 

이 링크는 지금 초기화되는 node를 구성하는 기본

. 이 변경 사항이 없으면 link 노드가 가비지 값 이었으므로 목록에 더 많은 항목을 삽입 할 때 링크를 제대로 탐색하지 못했습니다.

변경이 같은 유사한 (하지만 완전히)이다

class node { 
private: 
    double num; 
    node *link; 
public: 
    node() { link = 0; } // here is the change here 
    //... 
    //... the rest of your code 
}; 

차이점은 첫 번째 예는 0에 대한 링크를 초기화하면서 link가 여기 생성자 본문에 할당된다는 것이다 생성자가 시작되기 전에 두 사람 모두 똑같은 일을합니다.