связанный список C ++, вопрос самообучения - PullRequest
1 голос
/ 17 апреля 2011
        #include <iostream>
    using namespace std;



    struct Node
    {
        int item;   // storage for the node's item
        Node* next;   // pointer to the next node 
    };

  Node* addNode(Node*& head, int data , int& count) 
{
    Node * q;     // new node
    q = new Node;  // allocate memory for the new mode
    q->item = data;  // inserting data for the new node
    q->next = head;   // point to previous node ?? how would i do that? ( am i doing it correctly?)
    count++; // keep track of number of node
    head = q;
    return q;
}



    int main()
    {
        int a, count=0;
        int data;
        bool repeat;
        Node *head= NULL;   
        //^^ assuming thats creating the first node ^^
        do
        {
        cout << "please enter the data for the next node" <<endl;
        cin >> data;
        addNode(head, data, count);
        cout << "do you wish to enter another node? (enter true or false)" << endl;
        cin >>repeat;
        }
       while (repeat == true);


       // assuming this is the print function  
          while(head != NULL)
        {
            cout << "output" << temp->item << endl;
            cout << temp->next << endl;
        }

        system("pause");
        return 0; 
    }

ладно, я попытался добавить новый элемент в список, как бы я перемещал голову, как память LIFO (стек), чтобы последний элемент находился на самом верху ..

любая помощь будет оценена! В последнее время указатели и узлы портятся в моем мозгу ...

Ответы [ 4 ]

1 голос
/ 17 апреля 2011

У вас, кажется, есть некоторые недоразумения:

Ваша "голова" - начало списка. Это всегда начало.

Вы добавляете добавление элементов в связанный список, назначая их указателю next последнего узла.

В-третьих, вы ничего не выделяете.

Node *head= new Node();   
Node *temp = new Node();
cout<<"enter something into data"<<endl;
cin >> a ;
temp->item = a;
head->next = temp;

Теперь ... чтобы добавить следующую вещь, вам нужно либо отслеживать последний узел (хвост), либо пройти по списку, чтобы найти последний узел.

Node *nextNode = new Node();
nextNode->item = 0.0;
Node *i;
for (i = head; i->next != null; i = i->next);
i->next = nextNode;

Это O (n) время выполнения. Отслеживая хвост, вы делаете это O (1):

Node *head= new Node();
Node *tail = head;   
Node *temp = new Node();
cout<<"enter something into data"<<endl;
cin >> a ;
temp->item = a;
tail->next = temp;
tail = temp;

Node *nextNode = new Node();
nextNode->item = 0.0;
tail->next = nextNode;
tail = nextNode;

РЕДАКТИРОВАТЬ: Как указывалось, если вы хотите добавить к списку, вы бы:

temp->next = head;
head = temp;
1 голос
/ 17 апреля 2011

temp - неинициализированный указатель. Итак -

temp-> item = a;  // temp is not initialized or pointing to a memory location
                  // that has Node object to use operator ->

Сначала temp необходимо выделить ячейку памяти, используя new.

temp = new Node;
temp -> item = a;

А теперь назначьте его head. Аналогичным образом выделите память для дочерних узлов в цикле while. И верните все ресурсы, полученные от ребенка на голову, используя delete до завершения программы.

0 голосов
/ 17 апреля 2011

Так как я не уверен, что каждый ответ полностью отвечает на него, вот реализация связного списка (написано без testig:

// your (correct) structure
struct Node
{
    float item;   // storage for the node's item
    Node* next;   // pointer to the next node 
};

Теперь нам нужно два указателя где-нибудь, чтобы посмотреть список:

/* some pointers */
struct List
{
    Node* head;
    Node* tail;
};

Теперь нам нужно создать некоторые элементы. Как уже говорили другие, вы можете сделать это с новым:

/* create some elements we want to link in */
Node* elem1 = new Node();
Node* elem2 = new Node();
Node* elem3 = new Node();
/* maybe even set their properties! */
elem1->item = 3.14;
elem2->item = 3.14;
elem3->item = 3.14;

Обратите внимание, как я еще не пытался добавить эти элементы в список?Это потому, что я имею в виду функцию, которая выглядит следующим образом:

void addtolist(List &list, Node* node)
{
    /* if no head, initialise the list */
    if ( list->head == NULL )
    {
        list->head = node;
        list->tail = node;
    }
    else if ( list->head != NULL && list->tail != NULL )
    {
        /* access the tail element and set its 
           next to this ptr. 
           Move tail to this node */
        list->tail->next = node;
        list->tail = node;
    }
    else
    {
        /* probably raise an exception! */
    }
}

Вы можете вызвать это, выполнив это:

List l;
addtolist(l, elem1); /* etc */

Удаление элементов несколько сложнее, так как вынужно перейти к этому элементу, запомнить его предыдущий элемент, взять его следующий элемент, соединить их и удалить узел *, на котором вы находитесь.

Теперь для обхода списков ... ваша терминология HEAD|TAIL напоминает мнеErlang и хвостовой рекурсии, где текущий элемент упоминается как голова, а остальная часть хвоста. Если я напишу:

Node* cur = l.head;
while ( cur != NULL )
{
    // do something with cur.item ? 
    cur = cur->next;
}

Вы можете видеть это происходящее. Замена cur на head здесьбудет безвреднымanks к List struct.

Наконец, я использовал очень C-подобный подход здесь, но есть область применения для шаблонов:

template<typename T>
struct node
{
    T item;   // storage for the node's item
    Node<T>* next;   // pointer to the next node 
};

и инкапсуляция структуры Listкак класс:

template<typename T>
class List
{
protected:
    Node<T>* head;
    Node<T>* tail;
public:

    void addtolist(Node<T>* node);
    Node<T>* gethead();
    Node<T>* gettail();
}

Что немного приближает вас к std::list.

0 голосов
/ 17 апреля 2011

Дополнительно обратите внимание, что вы делаете неявное приведение от int до float на

temp-> item = a;

как a является int, а temp->item является double.

Для решения вашей проблемы: Вы хотите выделить новую структуру перед доступом к temp, таким образом

temp = new Node();
...