2012-09-02 8 views
2

현재 연결된 목록 구조를 연습 중이며 해당 알고리즘을 사용하여 프로그램을 작성했습니다. 이 프로그램에는 연결된 목록의 모든 요소를 ​​제거하는 재귀 적 메서드가 있습니다. 그러나 해당 메서드에서 프로그램이 충돌합니다.재귀 메서드 C++

void exit() 
{ 
    Person* person = phead; 
    exterminateStartingFrom(person); 
} 

void exterminateStartingFrom(Person* person) 
{ 
    Person* nextperson; 
    nextperson = person->getNext(); 
    if(nextperson){ 
     exterminateStartingFrom(nextperson); 
    } 
    delete person; 
} 

이 방법은 사용자가 종료 할 때 실행됩니다. "phead"는 사람 목록의 첫 번째 요소를 나타냅니다. 더블 무료 또는 손상 (fasttop)

여기 Person 클래스입니다 :

class Person { 
private: 
    std::string firstname; 
    std::string lastname; 
    int age; 
    Person* next; 

public: 
    Person(std::string, std::string, int); 
    void printDescription(); 
    void printFirstname(); 
    void printLastname(); 
    void printAge(); 
    void setNext(Person*); 
    Person* getNext(); 


}; 

감사 문제는 보여 주었다.

+5

'phead'가 NULL로 시작하면 함수가 실패하지만 그렇지 않으면 ok입니다. –

+2

많은 것들은 (i)'Person' 객체가 초기화되는 방법 (생성자)과 (ii) 그것들이 어떻게 파괴되는지 (destructor)에 달려 있습니다. – jogojapan

+1

'delete '를 호출 할 때 일어나는 일을보기 위해서는 Person 소멸자를 보여줘야합니다. –

답변

1

목록이 단방향으로 연결 되나요? 양방향 목록 (포인터를 다음 요소뿐만 아니라 이전 요소까지 저장할 수 있음)에서 소멸자를 호출하면 previousnext 필드로 표시된 요소도 삭제할 수 있습니다. 재귀가 한 레벨 위로 돌아오고 마지막 요소 다음으로 삭제하려는 경우 오류가 발생합니다.

+0

아니요. 다음 일방 통행 목록입니다. –

+1

디버거를 사용해 보셨습니까? 나는 그것이 당신에게 단서를 줄 것이라고 생각합니다. 생성자 및 소멸자 메서드도 제공 할 수 있습니까? –

+0

방금 ​​해보았습니다. 감사. 이 방법에는 문제가 없었습니다. –

1

Person 객체를 생성하거나 삭제하는 방법을 알지 못해도 말하기 어렵습니다. 오류 메시지는 동일한 항목을 두 번 삭제하거나 할당되지 않은 항목을 삭제한다는 의미입니다. 한 번 이상 삭제 된 동일한 주소가 있는지 확인할 수 있도록 삭제하려고하는 주소를 인쇄 해보십시오.

또한 재귀 메서드에 전달할 포인터가 nill 인 경우를 처리하십시오.

1

다음은 내가 취한 접근 방식입니다. 당연히 이것은 당신의 실제 기능을 모르기 때문에 다소 인위적입니다. 또한 pHead를 초기 전역 변수로 나타내며 범위를 벗어나는 값을 가진 나이를 사용하여 목록의 머리를 나타냅니다.

목록 맨 앞에 나는 특수 생성자를 사용합니다.

이 작업을 수행하는 더 좋은 방법이 있지만, 빠르고 순결한 구현에서는 내가 목록의 헤드를 완전히 뒤 졌을 때 내가 알고있는 재귀 중에 철회 할 때 표시해야 할 것이 있습니다.

#include <string> 

class Person { 
private: 
    std::string firstname; 
    std::string lastname; 
    int age; 
    Person* next; 

public: 
    Person (void);       // constructor for the pHead 
    ~Person (void); 
    Person(std::string, std::string, int); // standard constructor used 
    std::string getFirstname(void) { return firstname; }; 
    std::string getLastname(void) { return lastname; } 
    void setNext(Person *newNext) { next = newNext; } 
    Person* getNext() { return next; } 
    Person *addToListAt (Person *personList); 
    void addToListAtEnd (Person *personList); 
    void Person::insertListAfter (Person *personList); 
    bool isHeadOfList (void); 
}; 

Person pHead = Person(); 

// special constructor used to create the head to a linked list 
Person::Person() 
{ 
    age = -1; 
    next = 0; 
} 

// standard constructor used to create a list item. 
Person::Person (std::string sFirstName, std::string sLastName, int myAge) 
{ 
    if (myAge < 0) myAge = 0; 
    firstname = sFirstName; 
    lastname = sLastName; 
    age = myAge; 
    next = 0; 
} 

Person::~Person() 
{ 
    next = 0; 
    age = 0; 
} 

void exterminateStartingFrom(Person* person) 
{ 
    Person* nextPerson; 
    nextPerson = person->getNext(); 
    if(nextPerson){ 
     exterminateStartingFrom(nextPerson); 
    } 

    if (! person->isHeadOfList()) 
     delete person; 
} 

Person *Person::addToListAt (Person *personList) 
{ 
    Person* nextPerson; 
    nextPerson = personList->getNext(); 
    personList->setNext (this); 
    return nextPerson; 
} 

void Person::insertListAfter (Person *personList) 
{ 
    Person* nextPerson; 
    nextPerson = personList->getNext(); 
    personList->setNext (this); 
    next = nextPerson; 
} 

void Person::addToListAtEnd (Person *personList) 
{ 
    Person* nextperson; 
    nextperson = personList->getNext(); 
    if(nextperson){ 
     addToListAtEnd (nextperson); 
    } else { 
     personList->setNext (this); 
    } 
} 

bool Person::isHeadOfList (void) 
{ 
    // we use a special age to represent the head of the list 
    // the head does not contain any data except for point to first item 
    // in the list. 
    return (age < 0); 
} 

int main(int argc, char * argv[]) 
{ 
    Person *newPerson = new Person("first_1", "last_1", 11); 
    newPerson->addToListAtEnd (&pHead); 
    newPerson = new Person("first_2", "last_2", 22); 
    newPerson->addToListAtEnd (&pHead); 
    newPerson = new Person("first_3", "last_3", 33); 
    newPerson->addToListAtEnd (&pHead); 

    Person *itemPerson = pHead.getNext(); 
    newPerson = new Person("first_11", "last_11", 12); 

    newPerson->insertListAfter (itemPerson); 

    exterminateStartingFrom(&pHead); 
    return 0; 
}