0

我正在尝试使用链表实现堆栈。我的pop()功能有问题。它可以编译,但是当我尝试运行代码时它崩溃了tmp=tmp->head;,我不知道为什么。我试过谷歌但没有找到答案。这是完整的代码:

struct node{ //kreiram stog

    struct node* head;
    struct node* next;
    int broj;

}node;

void push_onto(int broj){ // dodajem na glavu

    struct node* novi;
    novi=(struct node*)malloc(sizeof(struct node));
    //novi=novi->head;
    if (novi== NULL)
        printf("Smth is wrong,Jose!\n");

    else

        novi->broj=broj;
        novi->next=novi->head;
        novi->head=novi;
}

int pop()// skidam sa stoga
{
    struct node* temp;
    temp=temp->head;
    int br;
    if (temp->next==NULL)
        return -1;
        else

        br=temp->head;
        temp=temp->next;
        free(temp);
        return br;

}

void top(){ //koji je element na stogu

    struct node* tmp;
    printf("Trenutni element na stogu je %d",tmp->broj);

}


void is_empty(){

    struct node* tmp;
    tmp=tmp->head;
    if (tmp->head ==NULL)
        printf("List is empty!\n");
}


void print_elem(){

    struct node* tmp;
    tmp=tmp->head;
    if (tmp->head==NULL)
        printf("Smth gone wrong!\n");

    while (tmp!=NULL)
    {
        printf("Number is: %d",tmp->broj);
        tmp=tmp->next;

    }
printf("\n");

}


int main(void){

push_onto(15);
push_onto(10);
push_onto(20);
push_onto(12);
//print_elem();
printf("The element removed is : %d",pop());
//print_elem();




return 0;

}

这不是我的作业,虽然看起来是这样。这只是我试图找出一些基本算法的尝试。提前致谢!:)

4

2 回答 2

3
struct node* temp;
temp=temp->head;

你从来没有为temp. 它只是一个未初始化的指针。

目前尚不清楚您要弹出什么。您的pop()函数不接受任何参数,并且它不访问全局变量。同样,我在那里的大多数功能都看到了同样的问题。它们应该对某种堆栈对象进行操作,但它们实际上都没有将这样的对象作为参数。

于 2013-04-26T23:36:16.150 回答
2

我认为你接近“得到它”。我记得一开始我有点难以理解结构和指针。但是一旦你“得到它”,你会没事的。

您似乎正在尝试使用简单链表构建堆栈。我会尽力提供一些建议。

我要修改的第一件事是你的node结构。确实,您需要跟踪头节点,但通常您不需要在每个节点上都这样做。因此,我们将从您的节点定义中删除它。

struct node{ //kreiram stog
    struct node* next;
    int broj;
};

现在,您需要跟踪列表的头节点。这可以通过一个全局变量来完成,我将其称为 head:

struct node* head = NULL;

我将它初始化为 null 因为它是空的。一个空头指针总是意味着你的堆栈是空的。所有试图操作列表的代码都需要从这个头节点开始。这是你的锚点。

然后到push_onto()函数

void push_onto(int broj){ // dodajem na glavu

    // this bit is fine
    struct node* novi;
    novi=(struct node*)malloc(sizeof(struct node));
    if (novi== NULL)
        printf("Smth is wrong,Jose!\n");

    else {   //I'm adding the bracket, you require it to enclose more than one statement
             //in the else section 
        novi->broj = broj;  // store the number to be pushed on the stack
        novi->next = head;  // link the list, remember head  will
                            // be NULL if the stack was empty
        head = novi;        // make the new node the current head node
   }
}

让我们修改 pop() 函数

int pop()// skidam sa stoga
{
    struct node* temp;
    int result;
    // first we will check if the head node is NULL (stack is empty)
    if( head == NULL ) {
        printf("Stack is empty\n"); 
        return -1;
    } else {
       // hold a temporary value to current head pointer, so we can modify the head node  
       // and still refer to it
       temp = head;
       // Head node should now point to the next node on the list (will become NULL when
       // popping the last value. This is what actually "pops" the value from our list
       head = head->next;
       // place in temporary variable the result we are popping. This is so because
       // it's not a good idea to reference the node after we free the memory it is using
       result = temp->broj;  
       // release the memory occupied by the node we're popping
       free(temp);
       return result;
   }
}

最后,我将向您展示如何修复一些正在使用您的堆栈的函数

void top(){ //koji je element na stogu

    if( head == NULL ) {
       printf("Stack is empty\n");
    } else {
       printf("Trenutni element na stogu je %d",head->broj);
   }
}


void print_elem(){
    struct node* tmp;
    // As you can see, we're initializing tmp to head, since head will always point
    // to the top element of your stack.

    tmp = head;
    if (tmp==NULL) {
        printf("Stack is empty!\n");
        return;
    }

    while (tmp!=NULL)
    {
        printf("Number is: %d",tmp->broj);
        tmp=tmp->next;

    }
   printf("\n");
}

希望事情现在更清楚了。头节点作为一个全局变量被分开,正如我之前所说,它是开始操作列表的锚点。如果您仍然感到困惑,请随时问我。

=)

于 2013-04-27T00:52:40.773 回答