2016-08-31 3 views
1

У меня есть этот код, через который он вставляет узел при запуске. Этот код также содержит функцию, которая печатает связанный список, а если она пуста, то печатает - связанный список пуст..Узел Вставка, связанные списки

Когда я запускаю этот код, у меня есть мой вывод, как Связанный список пуст.

struct node { 
    int data; 
    node* next; 
}* start = NULL; 

void append(node* linkedlist, int data) 
{ 
    node* new_element = NULL; 
    new_element = (node*)malloc(sizeof(struct node)); 
    new_element->data = data; 
    if (linkedlist == NULL) { 
     linkedlist = new_element; 
     new_element->next = NULL; 
    } 

    else { 
     new_element->next = (linkedlist)->next; 
     (linkedlist)->next = new_element; 
    } 
} 

int main() 
{ 
    append(start, 4); 
    append(start, 5); 
    printList(start); 
} 

Update:

void printList(node* linkedlist) 
{ 
    node* ptr = linkedlist; 
    if (linkedlist == NULL) { 
     printf("Linked list is empty"); 
     exit(0); 
    } 
    else { 

     while (ptr != NULL) { 
      cout << ptr->data; 
      ptr = ptr->next; 
     } 
    } 
} 

Что я мог бы, возможно, делать неправильно? Что я должен изменить, чтобы заставить его работать?

+0

И не используйте компилятор C++ для компиляции C. – wildplasser

+0

@nobar: строка 'void append (node ​​* linkedlist, int data) {' не сможет скомпилироваться в C, поскольку 'node' не является типом (нет typedef). Это всего лишь одно из отличий между C и (подмножество) C++ – wildplasser

+0

. @ KostasRim i пока не подтвердил это, я сделал этот метод раньше, я не знал о том, что значение передается как копия, следовательно, upvote .Плюс, я буду висеть на немного больше, чтобы увидеть еще несколько ответов :) –

ответ

3

Ваша проблема здесь linkedlist = new_element; При передаче аргументов функции они передаются по значению. Даже когда вы проходите pointer, вы фактически передаете копию этого указателя (вы можете проверить, напечатав адрес linkedlist внутри функции и вне функции). В заявлении linkedlist = new_element; присваивается копия new_element. Как только функция вернется, вы не получите ничего (и утечка памяти). Помните, когда вам нужно сменить указатель, вы должны использовать двойное pointer **

+2

или если OP не хочет ваш 'указатель **', они могут просто вернуть новый связанный список: 'node * append (node ​​* linkedlist, int data) {...' – meetaig

+1

Или перейдите по ссылке' void append (node ​​* & linkedlist, int data) ' – NathanOliver

+0

@NathanOliver Он использовал' malloc() ', и я сделал предположение, что он упустил тэг C++. Во всяком случае, я сделал редактирование, спасибо за указание! – KostasRim

2

Вы положите в поле значение start, что указывает на нуль. Затем вы скопируете его на другой указатель linkedlist и установите для него новое значение. После того, как функция start все еще указывает на нуль, хотя из-за того, что вы никогда не меняли значение start.

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

void append(node *&linkedlist,int data) 

Если вы используете C++ компилятор.

еще

void append(node **linkedlist,int data) 
... 
append(&start,4); 

, если вы используете C

0

В функции дописывания вы должны

  1. Первые инициализируете следующие из newnode утратившими
  2. Проверки перед установкой для пустого списка , если пусто, тогда сделайте это как голова.
  3. Если он не пуст, сделайте новый узел точкой заголовка вашего списка и сделайте его новой головой.
  4. Чтобы отразить вставку, сделанную в приложении, вы должны вернуть измененную головку из функции (также соответствующим образом изменить основной).

Посмотрите на этот код: -

node *append(node *linkedlist,int data){ 
     node *new_element=NULL; 
     new_element=(node *)malloc(sizeof(struct node)); 
     new_element->data=data; 
     new_element->next=NULL;// initialise next of newnode to be null here 
     // In case of empty list make this as first node 
     if(linkedlist==NULL) 
     { 
       linkedlist=new_element; 
     } 
     else 
     { 
      new_element->next=(linkedlist);//point the new node to head of list 
      (linkedlist)=new_element;// make new node as head 
     } 
     return linkedlist; 
    } 


    int main() 
    { 
     start = append(start, 4); 
     start = append(start, 5); 
     printList(start); 
    } 
+0

У этой проблемы есть проблема с OP – Hayt

+0

Извините, что обработано сейчас – rishabh

0

Я не думаю, что ваш, если утверждение верно. Я бы сделал это вот так:

if(linkedlist == null) 
{ 
    //head node is null i.e, linked list is empty hence make the new node as head node 
    linkedlist = new_element; 
}else{ 
    //make the new node point to the head 
    new_element->next = linkedlist; 
    //make the new node as head node 
    linkedlist = new_element; 
} 
2

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

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

Кроме того, это еще блок кода

else { 
     new_element->next = (linkedlist)->next; 
     (linkedlist)->next = new_element; 
    } 

неправильно. Этот кодовый блок не вставляет новый узел в начало списка. Он вставляет новый узел после первого уже существующего узла.

Учтите, что имя функции append не подходит для установки узла в начале списка. Лучше назвать его как insert. Функция может выглядеть следующим образом

int insert(struct node **linkedlist, int data) 
{ 
    struct node *new_element = malloc(sizeof(struct node)); 
    int success = new_element != NULL; 

    if (success) 
    { 
     new_element->data = data; 
     new_element->next = *linkedlist; 
     *linkedlist = new_element; 
    } 

    return success; 
} 

Если вы действительно нужен функция, которая присоединяет узлы в список, то он может выглядеть следующим образом

int append(struct node **linkedlist, int data) 
{ 
    struct node *new_element = malloc(sizeof(struct node)); 
    int success = new_element != NULL; 

    if (success) 
    { 
     new_element->data = data; 
     new_element->next = NULL; 

     while (*linkedlist != NULL) linkedlist = &(*linkedlist)->next; 
     *linkedlist = new_element; 
    } 

    return success; 
} 

Вот демонстративной программа

#include <stdlib.h> 
#include <stdio.h> 

struct node 
{ 
    int data; 
    struct node* next; 
} *start = NULL; 

int insert(struct node **linkedlist, int data) 
{ 
    struct node *new_element = malloc(sizeof(struct node)); 
    int success = new_element != NULL; 

    if (success) 
    { 
     new_element->data = data; 
     new_element->next = *linkedlist; 
     *linkedlist = new_element; 
    } 

    return success; 
} 

int append(struct node **linkedlist, int data) 
{ 
    struct node *new_element = malloc(sizeof(struct node)); 
    int success = new_element != NULL; 

    if (success) 
    { 
     new_element->data = data; 
     new_element->next = NULL; 

     while (*linkedlist != NULL) linkedlist = &(*linkedlist)->next; 
     *linkedlist = new_element; 
    } 

    return success; 
} 

void printList(struct node* linkedlist) 
{ 
    if (linkedlist == NULL) 
    { 
     puts("Linked list is empty"); 
    } 
    else 
    { 
     for (struct node *current = linkedlist; current != NULL; current = current->next) 
     { 
      printf("%d ", current->data); 
     } 
     printf("\n"); 
    } 
} 

int main(void) 
{ 
    const int N = 10; 

    for (int i = 1; i <= N; i++) 
    { 
     if (i % 2 == 0) append(&start, i); 
     else insert(&start, i); 
    } 

    printList(start); 

    return 0; 
} 

Его выпуск -

9 7 5 3 1 2 4 6 8 10 
0

Когда вы передаете параметр в C, он создает локальную копию используемой функции. Когда вы изменяете параметр внутри функции, он изменяет только локальную копию.

void f1(int a) 
{ 
    a = 1; // modification does not affect the calling function 
} 

int b=0; 
f1(b); 
assert(b == 0); // b was not changed by f 

В C (или C-стиле C++), если вы хотите функцию для изменения параметра необходимо передать его в качестве указателя:

void f2(int * a) 
{ 
    (*a) = 1; 
} 

int b=0; 
f2(&b); 
assert(b == 1); // b was changed by f 

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

void f3(int * * a) 
{ 
    (*a) = (int*) malloc(sizeof(int)); 
    (**a) = 1; 
} 

int * b = NULL; 
f3(&b); 
assert(b != NULL); // the pointer was initialized 
assert(*b == 1); // the pointed-to value was initialized 

процесс назначения может быть немного проще в C++, потому что вы можете использовать reference parameters вместо явного указания указателя.

+0

Оба подхода работают на C++, который является более или менее надмножеством C. – nobar

Смежные вопросы