2013-04-26 145 views
0

我想实现一个链接列表的堆栈。我遇到了pop()函数的问题。它编译好,但是当我尝试运行代码时,它在tmp=tmp->head;上崩溃,我不知道为什么。我试过谷歌,但没有找到答案。这里是完整的代码:Pop()函数崩溃

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; 

} 

这不是我的家庭作业,虽然它看起来像这样。这只是我试图找出一些基本算法的尝试。 在此先感谢! :)

回答

2

我认为你已经接近“明白了”。我记得我一开始就很难理解结构和指针。但是一旦你“明白了”你就会好起来的。

看来你正试图使用​​简单链表来构建一个堆栈。我会尝试提供一些建议。

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

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

现在,您需要跟踪列表的头节点。这可以用一个全局变量来完成,我要去打电话头:

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 
    } 
} 

让我们修改弹出()函数

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"); 
} 

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

=)

+0

非常感谢!正如你所说我正在接近它,这只是一些事情,但仍然bug我。我是那些必须“看到它”才能完全理解它的人之一,但是对于编程而言,这听起来很奇怪。 :)) 不管怎样,谢谢! – Nebbs 2013-04-27 03:28:13

+0

大声笑,相信它,我们必须“看到它”。我开始在BASIC中编程,并且我记得我已经直观地应用了指针和间接的概念,通过使用一个本身包含索引的数组到第二个数组。当我被介绍给帕斯卡尔的指针时,我花了一段时间才弄清楚这个事实!保持。很高兴我能够帮助! – 2013-04-27 16:13:31

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

您从未为temp分配过任何东西。这只是一个未初始化的指针。

目前尚不清楚你试图弹出什么。您的pop()函数不接受任何参数,并且它不访问全局变量。同样的,我也看到了你们大部分功能的相同问题。它们应该在某种堆栈对象上运行,但是它们中没有一个实际上将这样的对象作为参数。

+0

会全局变量解决问题吗?为什么? :S – Nebbs 2013-04-26 23:44:38

+0

忘掉全局变量并备份一下。所有你的函数本质上都是作用于堆栈对象的成员函数。所以为了完成他们的工作,他们需要实际上将栈对象作为参数。我看到他们中没有一个真的这样做。他们似乎创造了本地的东西。 – Kyurem 2013-04-26 23:46:54

+0

好吧,现在解决方案可以分配push()中的每个类型,或者接收指向堆栈的指针..? – Nebbs 2013-04-26 23:59:35