указатель на указатели для односвязного списка в C

У меня есть вопрос о явно связанных списках в C. Я создал связанный список с кодом, показанным ниже:

#include <stdio.h>
#include <stdlib.h>
struct node 
{
    int data;
    struct node* next;
};

struct node *mknode(int data)
{
    struct node* np=malloc(sizeof(struct node));
    np->data=data;
    np->next=NULL;
    return np;
}

struct node * insert (struct node* list,int data)
{
    struct node *np;
    struct node*curr=list;
    struct node* prev=NULL;
    np=mknode(data);
    for(;curr &&data<curr->data;curr=curr->next )
        prev=curr;


    np->next=curr;
    if(prev)
        prev->next=np;
    else
        list=np;
    return list;
}


int main()
{
    struct node* head;
    head=malloc(sizeof(struct node));
    head=insert(head,7);
    head=insert(head,2);
    head=insert(head,4);
    printf("%d",head->data);
    printf("%d",head->next->data);
    printf("%d",head->next->next->data);
    return 0;
}

Однако во время поиска в Интернете я понял, что двойной указатель используется для создания связанного списка вместо обычного указателя. Я имею в виду struct node **list , а не struct node * list . Интересно, почему ? Какой из них правильный, и если оба из них верны, в чем разница между ними, я использовал свою реализацию с основным образцом, который я написал здесь, и он работает нормально, но я не знаю, почему я должен использовать указатель на указатели? Заранее спасибо.

head=malloc(sizeof(struct node)); голова неправильно инициализирована.   —  person caesar    schedule 06.08.2013

@PeterMiehle Я не узнаю вопрос, который вы здесь указали. Извините за дубликат, но я не делал этого для дублирования цели.   —  person caesar    schedule 06.08.2013

См. также:  Ошибка подключения к локальному эмулятору функций Firebase из приложения Flutter
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 5
  1. caesar

    Причина, по которой некоторые люди используют указатель на указатель, заключается в том, что узлы могут быть обновлены без возврата нового указателя. В вашем примере, если вы хотите изменить указатель головы, вам нужно будет создать новый указатель, а затем сделать голову равной этому указателю. С помощью двойного указателя вам нужно только освободить пространство, на которое указывает второй указатель, а затем обновить второй указатель до вашей новой структуры данных, которая сохраняет исходный указатель головы.

    Я просто использую один указатель в своих реализациях.

  2. caesar

    Читайте здесь, таким образом вы можете изменять элементы, не создавая новых.

    В чем причина за использование двойного указателя при добавлении узла в связанный список?

  3. caesar

    Данный

    struct node { int x; };
    struct node **pplist;
    struct node *plist;
    

    pplist — указатель на указатель на struct node, а plist — указатель на struct node. Чтобы изменить x, вам нужно написать

    *pplist->x = 3;
    plist->x = 4;
    

    Вы должны использовать указатель на указатель, если хотите, чтобы одна и та же переменная указывала, скажем, на разные списки, или если вы хотели передать указатель функции с побочным эффектом изменения этого указателя.

  4. caesar

    Это выглядит прекрасно для меня.

    Все, что есть в указателе, это адрес памяти куда-то. Двойной указатель — это просто адрес памяти на другой адрес памяти, который указывает на некоторые данные.

    Может быть, вы можете опубликовать, где вы видели node **list, и мы сможем объяснить это лучше, но пока ваш код выглядит хорошо.

    функция mknode точно такая же, но вот функция вставки, использующая двойной указатель: codepad.org/pYe3sfoM person caesar; 06.08.2013

  5. caesar

    это немного естественно, если вы вызываете «head = NULL; insert(&head, data);» который затем указывает на первый элемент. Все функции, которые предполагают изменение содержимого, должны вызываться косвенно. НО: это вопрос соглашения о кодировании. Кому-то нравится горячее, кому-то холодное. Проблема с head=insert(head, data); то есть эта голова непригодна для использования, если вы забудете «head=»

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: