2010-05-10 5 views
1

문제는 내가 작성한 삽입 기능과 함께 나타납니다.삽입 된 링크 된 목록 문제

3 조건이 작동해야합니다. b/w 1 및 2, b/w 2 및 3을 테스트했으며 마지막 요소로 작동했습니다.


EDIT; 그것은 내 자신의 문제였습니다. 나는 MAXINPUT = 3 (4 대신)을 넣었다는 것을 몰랐다. C++의 더 진보되고 간결한 기능을 사용하여 더 나은 프로그래머가되는 데 도움이되는 모든 노력에 감사드립니다.

기본적으로 문제가 해결되었습니다.


효율성은 아직 (아직) 내 관심사가 아닙니다. 이 디버그 과정을 안내해주십시오.

대단히 감사합니다.

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

    struct List // we create a structure called List 
    { 
     string name; 
     string tele; 
     List *nextAddr; 
    }; 

    void populate(List *); 
    void display(List *); 
    void insert(List *); 

    int main() 
    { 
     const int MAXINPUT = 3; 
     char ans; 

     List * data, * current, * point; // create two pointers 
     data = new List; 
     current = data; 

     for (int i = 0; i < (MAXINPUT - 1); i++) 
     { 
     populate(current); 
     current->nextAddr = new List; 
     current = current->nextAddr; 
     } 

    // last record we want to do it sepeartely 

     populate(current); 
     current->nextAddr = NULL; 
     cout << "The current list consists of the following data records: " << endl; 
     display(data); 

    // now ask whether user wants to insert new record or not 

     cout << "Do you want to add a new record (Y/N)?"; 

     cin >> ans; 

     if (ans == 'Y' || ans == 'y') 
     { 
    /* 

    To insert b/w first and second, use point as parameter 
    between second and third uses point->nextAddr 
    between third and fourth uses point->nextAddr->nextAddr 
    and insert as last element, uses current instead 

    */  
    point = data; 
    insert(()); 
     display(data); 
     } 

     return 0; 
    } 


    void populate(List *data) 
    { 
     cout << "Enter a name: "; 
     cin >> data->name; 
     cout << "Enter a phone number: "; 
     cin >> data->tele; 

     return; 
    } 

    void display(List *content) 
    { 
     while (content != NULL) 
     { 
     cout << content->name << "  " << content->tele; 
     content = content->nextAddr; 
     cout << endl; // we skip to next line 
     } 

     return; 
    } 

    void insert(List *last) 
    { 
     List * temp = last->nextAddr; //save the next address to temp 
    last->nextAddr = new List; // now modify the address pointed to new allocation 
     last = last->nextAddr; 
     populate(last); 
     last->nextAddr = temp; // now link all three together, eg 1-NEW-2 

     return; 
    } 
+0

어리석은 질문을 함축하십시오 : 당신은 흑백으로 무엇을 의미합니까? 그리고 insert (())는 무엇을합니까? 평균? 감사합니다 – Simon

+0

b/w는 위와 같은 매개 변수를 삽입하고 삽입 (삽입)을 의미합니다. 예를 들어, insert ((point-> nextAddr)). – CppLearner

답변

2

내 컴퓨터에서 코드가 정상적으로 작동합니다 (코드 설명에 설명 된대로 insert(()) 문을 올바르게 채우면됩니다). 삽입은 모든 위치에서 작동합니다. 다른


뭔가, 그래도 : 나는 처음에 insert 기능을 살펴했다. 먼저 새로운 별도의 항목을 만들기 때문에

void insert(List *last) 
{ 
    // create a new item and populate it: 
    List* new_item = new List; 
    populate(new_item); 

    // insert it between 'last' and the item succeeding 'last': 
    new_item->nextAddr = last->nextAddr; 
    last->nextAddr = new_item; 
} 

이 바람직 할 것이다, 삽입 준비를하십시오 : 나는 무슨 일 나는 당신에게 조금 짧고 무엇을 이해하기 쉽게 만드는 방법에 대한 힌트를 줄 거라고 생각 , 그리고 나서 이것이 성공적으로 작동했을 때, 함수는 링크 된리스트와 함께 "엉망"될 것입니다. 즉, 링크 된 목록은 마지막 문장을 제외하고는 영향을받지 않으므로 함수가 "안전합니다". 이것을 insert 버전과 비교하십시오. 여기서 실제 삽입으로 새 항목을 구성하기위한 코드를 혼합하십시오. 이 함수 내에서 무언가 잘못되면 링크 된 목록이 엉망이 될 확률이 훨씬 높습니다.

(무엇 여전히 BTW 빠진 것은 전달 된 인수 last 즉, 실제로 유효한지 여부를 초기 검사하지 널 포인터...)


PS : 물론 방금 ​​표준을 사용할 수 있습니다 C++ std::list 컨테이너 자체의 링크 된 목록을 작성하는 대신 컨테이너에 beginner이라는 태그가 붙어있는 것을보고, 실제로 작동하는 방법을 배우고 싶다고 가정합니다.

+0

'insert (());를'insert (point);'로 변경해야 제대로 작동합니까? 나는 그렇게 생각할 것이다. –

+0

예. 코드 주석에서 언급 한 것처럼'insert (point-> nextAddr);와'insert (point-> nextAddr-> nextAddr);도 시도했다. – stakx

+0

wooo stakx 매우 스마트 한 움직임입니다. 당신의 제안에 감사드립니다. – CppLearner

1

단계는 하나의 객체로 목록을 작성하는 대신 단지 main() 주위 포인터의 무리를 유지하기위한 것이어야한다. 자신의 첫 번째 (어쩌면 마지막 요소)에 대해 알고있는 List이라는 객체가 필요합니다. List.append()List.insert()과 같은 메소드도 있어야합니다.

현재 코드는 읽을 수 없습니다.

+0

안녕하세요. 고맙습니다. 우리 수업은 컴퓨팅에 대한 신입생 소개입니다. 그래서 우리는 (가장 기본적인 컴퓨팅 전략을 이해하는 대신) 어떤 사전 기능을 다루지 않았습니다. 프로그래밍에 꽤 단단한 배경이 있고 스택 (데이터 구조)에서 추가 및 삽입을 기억합니다. 고맙다 lgor! – CppLearner

1

숙제가 아니라면 std :: list를 사용하십시오.이 경우 숙제이므로 태그 지정이 필요합니다.

1

내 경험에 비추어 볼 때 작고 테스트를 시작한 다음 구축하는 방법을 배웠습니다. 이 단계들을 안내해 드리겠습니다.

현재 연결된 목록은 노드의 컨테이너입니다. 먼저 노드 클래스부터 시작하겠습니다.

최소는 노드가 다른 노드에 대한 포인터가 있어야합니다

#include <iostream> 
#include <cstdlib> // for EXIT_SUCCESS 
#include <string> 

using std::cout; 
using std::endl; 
using std::cerr; 
using std::cin; 
using std::string; 

struct Node 
{ 
    // Add a default constructor to set pointer to null. 
    Node() 
    : p_next(NULL) 
    { ; } 

    Node * p_next; 
}; 

// And the testing framework 
int main(void) 
{ 
    Node * p_list_start(NULL); 

    // Allocate first node. 
    p_list_start = new Node; 

    // Test the allocation. 
    // ALWAYS test dynamic allocation for success. 
    if (!p_list_start) 
    { 
    cerr << "Error allocating memory for first node." << endl; 
    return EXIT_FAILURE; 
    } 

    // Validate the constructor 
    ASSERT(p_list_start->p_next == 0); 

    // Announce to user that test is successful. 
    cout << "Test successful." << endl; 

    // Delete the allocated object. 
    delete p_list_start; 

    // Pause if necessary. 
    cin.ignore(100000, '\n'); // Ignore input chars until limit of 100,000 or '\n' 

    return EXIT_SUCCESS; 
} 

컴파일을하고,이 간단한 테스트를 실행합니다. 오류가 수정 될 때까지 수정하십시오.

다음에, 두 개의 노드를 연결하는 테스터를 수정

INT 본체 (공극) { 노드 * p_list_start (NULL); 노드 * p_node (NULL); // < - 두 번째 노드에 대한 새 명령문입니다. // ...

// Validate the constructor 
    ASSERT(p_list_start->p_next == 0); 

    // Allocate a second node. 
    p_node = new Node; 
    if (!p_node) 
    { 
     cerr << "Error allocating memory for 2nd node." << endl; 

     // Remember to delete the previously allocated objects here. 
     delete p_list start; 

     return EXIT_FAILURE; 
    } 

    // Link the first node to the second. 
    p_list_start->Link_To(p_node); 

    // Test the link 
    ASSERT(p_list_start.p_next == &p_node); 

    //... 

    // Delete the allocated object(s) 
    delete p_list_start; 
    delete p_node; 

    //... 

} 변형과

컴파일한다.
컴파일하지 못했습니다. 정의되지 않은 메서드 : Node :: Link_To
걱정하지 않아도됩니다. 컴파일러가 작동하고 있음을 보여줍니다. :-)

Node 구조에 Link_To 방법을 추가

struct Node 
{ 
    // ... 
    void Link_To(const Node& n) 
    { 
    p_next = &n; 
    return; 
    } 
    //... 
}; 

컴파일 및 실행됩니다. 테스트가 통과해야합니다.

이 시점에서 연결 프로세스가 확인되었습니다. 노드에 내용 추가.

Node 객체는 테스트되었으므로 노드 객체를 만지지 않습니다. 당신이 기능을 추가 할 수있는이 시점에서

struct Node 
{ 
    //... 
    std::string name; 
    std::string phone; 
} 

: 아직 상속을 배운하지 않은 경우

struct Name_Node 
: public Node // Inherit from the tested object. 
{  
    std::string name; 
    std::string phone; 
}; 

, 당신은 기존 노드에 추가 할 수 있습니다 : 그래서 내용으로 노드를 만들로부터의 상속하자 콘텐츠를 설정하고 표시하는 데 사용됩니다. 테스트 문을 추가하십시오. 실행하고 검증하십시오.

다음 단계는 두 개의 콘텐츠 노드를 만들어 함께 연결하는 것입니다. 빌드 할 때 테스트 코드를 보관하십시오. 또한, 물건이 작동하는 경우 별도의 기능으로 기능을 넣을 수 있습니다.

이 프로세스에 대한 자세한 내용은 Test Driven Development을 확인하십시오.

+0

안녕하세요. 문제가 확인 되었음에도 불구하고 여러분의 의견을 많이 주셔서 감사합니다 (나는 4 대신 잘못된 MAXINPUT = 3을 넣었습니다). 결승전이 끝날 때까지 나는 이것을 구할 것이다. 저는 C++을 정말 좋아합니다. 이러한 고급 기능은 매우 유용합니다. 네, 동의합니다. 나는 또한 동급생을 가르치고 있습니다 (비록 초보자 일지라도). 나는 평균 함수가 배열을 사용하는 것처럼 간단하게 시작한다고 말하고, 먼저 배열없이 평균 함수를 만드는 방법을 생각해 봅니다. 고마워요! – CppLearner