2016-10-03 2 views
1

Ich versuche, Stack als eine verkettete Liste zu implementieren. Hier ist mein aktueller Code:Linked List Implementierung von Stack

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

typedef struct node { 
    int data; 
    struct node* link; 
} Node; 

typedef Node* list; 

list head; 

void push(list top, int item) { 
    if (head == NULL) { 
     head = (list) malloc(sizeof(Node)); 
     head->data = item; 
     head->link = NULL; 
     top = head; 
    } else{ 
     list temp = (list) malloc(sizeof(Node)); 
     temp->data = item; 
     temp->link = top; 
     top = temp; 
    } 
} 

int pop(list top) { 
    if (top == NULL) { 
     printf("stack is empty"); 
     /*int tdata=top->data; 
     top=top->link; 
     return tdata;*/ 
    } else { 
     int tdata = top->data; 
     top = top->link; 
     return tdata; 
    } 
} 

void display(list top){ 
    while (top != NULL) { 
     printf("%d", top->data); 
     top = top->link; 
    } 
} 

int main() { 
    int ch, item; 
    list top; 

    for (;;) { 
     printf("1.push\t2.pop\t3.display\t4.exit"); 
     scanf("%d", &ch); 
     switch (ch) { 
      case 1: 
       printf("enter the element to be pushed"); 
       scanf("%d",&item); 
       push(top,item); 
       break; 
      case 2: 
       item=pop(top); 
       printf("element popped is: %d",item); 
       break; 
      case 3: 
       display(top); 
       break; 
      case 4: 
       exit(0); 
       break; 
      default: 
       printf("enter valid choice"); 
     } 
    } 
} 

Wenn ich drücke ‚2‘ die pop Methode aufgerufen wird, aber unabhängig davon, was auch immer Artikel ist auf der Oberseite druckt die Meldung „Element aufgetaucht ist: 11“. Wenn ich '3' für die Methode display drücke, bekomme ich "segmentation fault (core dumped)". Warum passiert dies? Welche Modifikationen sind nötig, damit dieser Code funktioniert?

+1

Willkommen bei Stack Overflow! Es klingt, als müssten Sie lernen, wie Sie einen Debugger verwenden, um durch Ihren Code zu gehen. Mit einem guten Debugger können Sie Ihr Programm Zeile für Zeile ausführen und sehen, wo es von dem, was Sie erwarten, abweicht. Dies ist ein essentielles Werkzeug, wenn Sie programmieren wollen. Weiterführende Literatur: [Wie kleine Programme zu debuggen] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

+1

Bitte lesen Sie, wie Sie Ihren Code einrücken. –

+1

Es scheint etwas Verwirrung darüber zu bestehen, ob die Liste "top" (main) oder "head" (global) ist. –

Antwort

1

Ich habe einige Änderungen an Ihrem Programm vorgenommen. Am wichtigsten ist es, einen Zeiger an den Listenkopf zu übergeben, der selbst ein Zeiger ist, damit er von der Funktion verändert werden kann.

Ich entfernte auch die globale head und initialisierte die lokale top. Ich habe im Code über andere Dinge kommentiert.

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

typedef struct node { 
    int data; 
    struct node *link; 
} Node;         // removed pointer type to Node 

void push(Node **top, int item) {  // takes address of the pointer 
    Node *temp= malloc(sizeof(Node)); // do not cast malloc 
    if(temp == NULL)     // check that malloc did work 
     exit(42); 
    temp->data = item;     // no need for separate clause at first push 
    temp->link = *top;     // link is previous top 
    *top = temp;      // top is new struct, pass it back 
} 

int pop(Node **top) {     // takes address of the pointer 
    int tdata; 
    Node *temp; 
    if (*top == NULL) { 
     printf("stack is empty\n");  // added newline here and other places 
     return 0; 
    } 
    tdata = (*top)->data;    // collect the data 
    temp = (*top)->link;    // remember the next list item 
    free(*top);       // give memory back 
    *top = temp;      // pass new top back to caller 
    return tdata; 
} 

void display(Node *top){ 
    while (top != NULL) { 
     printf("%d ", top->data);  // added spacing 
     top = top->link; 
    } 
    printf("\n");      // added newline 
} 

int main(void) { 
    int ch, item; 
    Node *top = NULL;     // initialise the list !! 

    do { 
     printf("1.push 2.pop 3.display 4.exit "); 
     scanf("%d", &ch); 
     switch (ch) { 
      case 1: 
       printf("enter the element to be pushed "); 
       scanf("%d",&item); 
       push(&top,item);  // pass address so pointer can be updated 
       break; 
      case 2: 
       item=pop(&top);   // pass address so pointer can be updated 
       printf("element popped is: %d\n",item); 
       break; 
      case 3: 
       display(top); 
       break; 
      case 4: 
       break; 
      default: 
       printf("enter valid choice\n"); 
     } 
    } while(ch != 4);     // changed the loop style 
} 
+0

danke für Ihre Hilfe.Ich schätze wirklich die Mühe, die Sie bei der Bereitstellung der richtigen Code genommen haben.Sie denken nicht, wenn wir die Anzeige-Methode einmal in Ihrem Code wird es den Wert von oben ändern und danach, wenn wir Pop Es wird angezeigt, dass der Stapel leer ist. –

+0

@sameersoin die Anzeigemethode übergibt nicht den Zeiger an Zeiger, so dass der Listenkopf nicht geändert werden kann. Sie machen den gleichen Fehler wie Sie ursprünglich getan haben: Das Funktionsargument ist eine * Kopie * von dem, was übergeben wurde. Der Grund für den Doppelzeiger (der "Anzeige" nicht benötigt) ist so, dass der übergebene Wert modifiziert werden kann. Eine andere Möglichkeit, dies zu tun, wäre, einen einzelnen Zeiger zu übergeben und einen neuen Zeiger als das Funktionsergebnis zurückzugeben, das "top" in "main" zugewiesen wäre. Aber im Fall von "Pop" müsste der Wert dann ein '*' Argument sein. Wenn Sie diese Antwort mögen, bitte "akzeptieren" Sie es. –

+0

Bitte beachten Sie, dass es 'display (top)' und nicht 'display (& top)' ist, da die 'push' und' pop' Funktionen verwendet werden. –

0

Was passiert ist, dass Sie einfach nicht initialisieren oder gesetzt jeder Wert auf Ihre Liste Zeiger top.
Werfen Sie einen guten Blick auf Ihre Einfügefunktion push. Es empfängt einen Zeiger. Wenn Sie Ihr Mitglied top als [out] Parameter an diese Funktion senden möchten, sollten Sie einen Zeiger auf einen Zeiger (**) oder einen Verweis auf einen Zeiger (*&) senden.
Senden top wie dies ändert seinen Wert nicht und hinterlässt es mit Junk, wie diese Variable auch nie initialisiert wurde ...