删除一个元素后,堆栈弹出操作无效

时间:2016-07-07 08:07:19

标签: c linked-list stack

我使用链表实现了堆栈。以下是C程序。

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

typedef struct StkElmt_{
    int data;
    struct StkElmt_* next;
}stackelmt;

typedef struct stack_{
    stackelmt* head;
    stackelmt* tail;
    int size;
}stack_t;



void stack_init(stack_t* stack){
    stack->head = NULL;
    stack->tail = NULL;
    stack->size = 0;
}


int stack_insert(stack_t* stack, int data){
    stackelmt* new_element = (stackelmt*)malloc(sizeof(stackelmt));
    new_element->data = data;
    if (stack->size = 0)
        stack->tail = new_element;
    new_element->next = stack->head;
    stack->head = new_element;
    stack->size++;
}
int stack_del(stack_t* stack){
    int data;
    stackelmt* old_element;
    if (stack->size == 0)
        return -1;
    data = stack->head->data;
    old_element = stack->head;
    stack->head = stack->head->next;

    if (stack->size == 1)
        stack->tail = NULL;

    free(old_element);
    stack->size--;
    return 0;
}

void printstack(stack_t* stack){
    stackelmt* point = (stackelmt*)malloc(sizeof(stackelmt));
    for (point = stack->head; point != NULL; point = point->next)
        printf("\n(_%d_)\n  ", point->data);


}


void insertfunction(stack_t* stack, int max){
    int x;
    for (int i=0; i<max; i++){
        scanf("%d", &x);
        stack_insert(stack, x);
    }
    printf("the stack is: \n");
    printstack(stack);
}


void deletefunction(stack_t* stack, int num){
    for (int j=0; j<num; j++)
        stack_del(stack);
    printstack(stack);
}

void utilityfunction(){
    int userinput, maxinput, maxdel;
    stack_t* stack = (stack_t*)malloc(sizeof(stack_t));
    stack_init(stack);
    while (1) {
        printf("\n1 to insert elements in the stack\n2 to delete elements in the stack\n3 to break\n");
        scanf("%d", &userinput);
        switch(userinput){
            case 1:
                printf("\nEnter how many elements you want to push into stack: ");
                scanf("%d", &maxinput);
                insertfunction(stack, maxinput);
                break;
            case 2:
                printf("\nEnter how many elements you want to pop from stack: ");
                scanf("%d", &maxdel);
                deletefunction(stack, maxdel);
                break;
            case 3:
                break;
            default:
                printf("Invalid input\n");
                break;
        }   
    }   
}

int main(){
    utilityfunction();
    return 0;
}

插入操作正常。例如:

Enter how many elements you want to push into stack: 5
1
2
3
4 
5
the stack is: 

(_5_)

(_4_)

(_3_)

(_2_)

(_1_)

但是删除功能在被调用时会弹出“数字”字样。堆栈中的元素数量。但是会发生以下情况。

Enter how many elements you want to pop from stack: 3

(_4_)

(_3_)

(_2_)

(_1_)

虽然我想从堆栈中弹出3个项目,但只弹出一个项目,即5。

代码中的错误是什么?

2 个答案:

答案 0 :(得分:2)

该行

stack_insert()
函数stack->size++;中的

会将大小设置为零,稍后stack_del()会将大小设置为1。

然后,if (stack->size == 0) 将查看大小并认为堆栈只有一个元素。弹出一个元素,堆栈似乎没有元素,因此删除第二个元素或以后不会发生。

您应该启用编译器警告并进行比较

stack_insert()

而不是函数printstack()中的赋值。

另请注意,composer.json中已分配的内存未被使用,它被丢弃并导致内存泄漏,您应该停止在那里分配。

还有一点需要注意:他们说you shouldn't cast the result of malloc() in C

答案 1 :(得分:1)

  

stack_insert功能if (stack->size = 0)必须为if (stack->size == 0)

原因:分配运算符=始终求值为true,您必须使用逻辑等于运算符==

因此,这意味着即使您的stack->size不是0,您也可以将其重新分配给0并执行stack->tail = new_element;

  

并使其返回类型为void,因为您没有从函数

返回任何内容
  • 所以,以下功能:

    int stack_insert(stack_t* stack, int data)
    {
      stackelmt* new_element = (stackelmt*)malloc(sizeof(stackelmt));
      new_element->data = data;
      if (stack->size = 0)
          stack->tail = new_element;
      new_element->next = stack->head;
      stack->head = new_element;
      stack->size++;
    }
    
  • 必须更改为:

    void stack_insert(stack_t* stack, int data) //change 1
    {
        stackelmt* new_element = (stackelmt*)malloc(sizeof(stackelmt));
        new_element->data = data;
        if (stack->size == 0) //change 2
            stack->tail = new_element;
        new_element->next = stack->head;
        stack->head = new_element;
        stack->size++;
    }
    

此外,

  • 不要使用int main()而是使用int main(void),因为int main()可以接受任意数量的参数,但是,这里您不发送任何参数 所以,int main(void)是合适的

  • 请勿关闭malloc()

  • 的返回值

例如:

stackelmt* new_element = (stackelmt*)malloc(sizeof(stackelmt));

将其更改为:

stackelmt* new_element = malloc(sizeof(stackelmt));

原因 malloc() 成功分配会返回void *类型,该类型会自动转换为指定的指针类型。