2014-03-30 2 views
0

나는 만들고있는 작은 게임을 위해 이중 링크 된 순환 목록을 만들고 싶습니다. 나는 그것이 새로운 요소를 추가하고 삭제할 때 제공하는 속도 때문에 그것을 목록으로 원한다. 역동적 인 테이블을 사용하고 싶다면 어떤 종류의 추가/삭제 작업을해도 전체 테이블을 다시 작성해야하고 프로그램이 심각하게 느려질 것입니다. 나는 사용자가 할 수 있도록하려면 무엇더블 링크 된 순환 목록 C++

struct parts{ 
    char name; 
    parts *next, *prev; 
    parts *connected; 
}; 

void add_part(struct parts **head, struct parts **tail, char name) 
{ 
    struct parts *a; 
    a = (struct parts*)malloc(sizeof(struct parts)); 
    a->name = name; 
    if ((*head) == NULL && (*tail) == NULL) 
    { 
     *head = a; 
     *tail = a; 
     a->next = NULL; 
     a->prev = NULL; 
    } 
    else 
    { 
     a->next = *head; 
     a->prev = NULL; 
    } 
} 

void display(parts *head) { 
    parts *temp = head; 
    while (temp != NULL){ 
     cout << temp->name << endl; 
     temp = temp->next; 
    } 
} 

int main() 
{ 
    char names[] = "ABCDEFGHIJKLMNOPRSTUWXYZ"; 
    segmenty *head = NULL; 
    segmenty *tail = NULL; 
    int count_parts; 
    cin >>count_parts; 

    for (int i=0; i < count_parts && i<24; i++){ 
     add_part(&head, &tail, names[i]); 
    } 
    display(head); 
    return 0; 
} 

그가 원하는 요소의 양을 입력하는 것입니다), 해당 솔루션에 대한 유일한 문제는 내가 완전히 같은 목록을 수행하는 방법을 이해하지 못하고 있다는 사실이다 그리고 나서 각 요소의 이름을 알파벳의 문자로 지정하고 목록에 넣으므로 모든 요소가 전후 요소에 연결되고 꼬리가 머리에 연결됩니다 (목록이 주기적 이길 원합니다). 안타깝게도 내 포인터 기술이 부족합니다 ... * connected는 새로운 요소를 삭제하거나 추가하는 등의 용도로 현재 지상에있는 요소 (단 하나의 요소 만 한 번에지면에 닿을 수 있음)에 사용하려는 포인터입니다. 요소가 함정에 부딪치게되면 그 특정 요소를 삭제하려고합니다. 다른 요소는 삭제하지 않습니다.

+0

를 당신이 읽을 것을 권장합니다 : 예를 들어, 다음 코드 조각입니다 http://en.wikipedia.org/wiki/Doubly_linked_list (특히 "순환 이중 연결 목록"섹션). 또한 분리 된 머리를 사용하는 것이 좋습니다 (즉, 첫 번째 요소를 머리로 사용하지 마십시오). 순환 이중 연결 목록을 만들기 전에 이미 간단한 목록을 만들었습니까? – Biduleohm

+0

전에는 그런 짓을하지 않았습니다. 완전히 새로운 개념입니다. – user3026386

+1

이 코드는 C ('malloc'과'struct parts')와 C++ ('cin'과'cout'과 함께)의 혼합으로 보입니다. 나는'malloc'을 없애고 대신에 C++의 기능을 사용하는 것을 권장합니다. – Edward

답변

1

포인터 기술을 연습하고 입증해야하는 경우가 아니면 여기 에 설명 된 std::list 컨테이너를 검토하십시오. 근본적으로 struct parts과 모든 포인터 조작은 사라질 것입니다. std::list 컨테이너는 요소 당 하나의 char을 저장하는 것으로 선언 할 수 있습니다. 그것은 또한 모든 포인터 조작과 관리를합니다. connected 포인터는 std::list 코드 샘플 다음에 설명되어 있습니다. 당신이 문자열이 더 나은 하나의 char를 저장하여 테스트 후 발견하면

후 대신 std::string을 포함하도록 std::list를 선언하는 형식 정의 라인을 수정합니다.

제거 기능에 대한 참조는 std::list::remove, remove_if입니다.

삽입 기능에 대한 참조는 std::list::insert입니다. 삽입은 여기서 설명하지 않지만 오버로드 된 버전은 8 가지입니다. 일정 시간 복잡도와

네 가지 방법 :
1.리스트의 앞이나 끝으로 추가 사용 : std::list::push_frontstd::list::push_back.
2. 앞면 또는 뒷면에서 단일 요소를 제거하십시오 (std::list::pop_frontstd::list::pop_back).


예제 선언과 간단한 조작이 이어집니다. std::list (예 using namespace std;가 존재) 명확성을 위해 아래와 같이하지만, std:: 컴파일하고 구축 할 필요가 없습니다되어

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

// 
// Other headers as needed, then a sample main... 
// 
main (int argc, char * argv[]) 
{ 
    const int ciNamesMax = 26; 
    char names[ciNamesMax] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 
           'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
           'U', 'V', 'W', 'X', 'Y', 'Z' }; 


    typedef std::list <char> tdCharNames; 
    tdCharNames theNames(names, names + ciNamesMax); 


    // 
    // Print the list contents with zero modifications to the elements 
    // 
    cout << "The doubly linked list of chars contains the following values."; 
    cout << endl; 
    int j = 1; 
    for (tdCharNames::iterator i = theNames.begin(); i != theNames.end(); i++) 
    { 
     cout << "Element " << j << " is: " << (*i) << endl; 
     j++; 
    } 

    // 
    // Use the built-in remove function in two different ways to demonstrate 
    // ease of removing an element or elements. 
    // 
    theNames.remove('B'); 

    // 
    // Note that the C++11 lambda function is used as the predicate to 
    // remove the 'G' and 'P' elements. 
    // 
    theNames.remove_if([](char c) { return (c == 'G' || c == 'P'); }); 
    j = 1; 
    for (tdCharNames::iterator i = theNames.begin(); i != theNames.end(); i++) 
    { 
     cout << "Element " << j << " is: " << (*i) << endl; 
     j++; 
    } 

} // end main 


위의 struct parts 내부의 connected에서 포인터를 선언 한 char 변수가 될 것입니다, (사용자로부터의 입력 및 cin). 그런 다음 connected 변수가 std::list::remove 함수에 전달됩니다.std::string 저장하는 스위칭

char connected; 
cout << "Enter the ground location (A-Z): "; 
cin >> connected; 

// 
// Other logic, user messages, error checking, and so on. 
// Then, call the std::list::remove method as desired. 
// 
theNames.remove(connected); 


예 :

const int ciNamesMax = 26; 
std::string names[ciNamesMax] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 
           "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 
           "U", "V", "W", "X", "Y", "Z" }; 


// 
// May want to modify the typedef name to better indicate std::string. 
// Leaving the typedef as before to demonstrate the simplicity of changing 
// the element type being stored. Keep in mind that the lambda and other 
// logic looking for a char may be affected. It is up to the reader to test 
// and adjust the implementation accordingly. 
// 
typedef std::list <std::string> tdCharNames; 
tdCharNames theNames(names, names + ciNamesMax);