在C中使用Linkedlist的堆栈实现

时间:2019-09-15 06:28:26

标签: c data-structures linked-list stack singly-linked-list

我已经用C语言编写了代码,以使用LinkedList算法实现堆栈。这是代码....

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct listNode {
int data;
struct listNode *next;
};
struct stack{
struct stack *top;
};
struct stack *createstk(){
    struct stack *stk;
    stk=malloc(sizeof(struct stack));
    stk->top=NULL;
    return stk;
}
void push(struct stack *stk,int data){
    struct listNode *temp;
    temp=malloc(sizeof(struct listNode));
    if(!temp){
        printf("heap overflow");
        return;
    }
    temp->data=data;
    temp->next=stk->top;
    stk->top=temp;
}
int pop(struct stack *stk){
    if(isEmpty(stk))
        return INT_MIN;
    int data;
    struct listNode *temp;
    temp= stk->top;
    stk->top=stk->top->next;
    data=temp->data;
    delete(temp);
    return data;
}
int peek(struct stack *stk){
    if(isEmpty(stk))
        return INT_MIN;
    return stk->top->data;
}
int isEmpty(struct stack *stk){
    return stk->top==NULL;
}
void deleteStack(struct stack *stk){
    struct listNode *temp,*p;
    p=stk->top;
    while(p){
        temp=p->next;
        p=p->next;
        free(temp);
    }
    free(stk);
}
int main(){
    int i=0;
    struct stack *stk=createstk();
    for(i=0;i<=10;i++)
        push(stk,i);
    printf("Top Element is %d",peek(stk));
    for(i=0;i<=10;i++){
        printf("popped element is %d",pop(stk));
    }
    if(isEmpty(stk))
        printf("stack is empty");
    else
        printf("stack is not empty");
    deleteStack(stk);
    return 0;
}

It is generate such errors like:

  

[警告]分配了不兼容的指针类型。   如您在图片上方所见。我是编码领域的新手,并且第一次遇到此错误。这就是为什么我不知道该怎么办的原因。请告诉我...

2 个答案:

答案 0 :(得分:0)

stack 类型的字段 top 具有错误的类型。更改

struct stack {
    struct stack *top;
};

struct stack {
    struct listNode *top;
};

答案 1 :(得分:0)

您有很多错误,stack->top的类型不正确,August Karlstrom正确指出,您的成员top的类型必须为struct listNode *top;,例如

struct stack {
    struct listNode *top;
};

在更正之后,您必须为isEmpty()deleteStack()重新排序函数或提供函数原型。在首次使用它们之前在代码中向上移动它们可以解决问题,例如

struct stack *createstk()
{
    struct stack *stk;
    stk = malloc (sizeof (struct stack));
    stk->top = NULL;
    return stk;
}

int isEmpty (struct stack *stk)
{
    return stk->top == NULL;
}

void deleteStack (struct stack *stk)
{
    struct listNode *temp, *p;
    p = stk->top;
    while (p) {
        temp = p->next;
        p = p->next;
        free (temp);
    }
    free (stk);
}
...

接下来,这是C语言,而不是C ++语言,没有delete函数可以释放内存,因此在pop()中,您必须调用free (temp);而不是delete (temp);

最后,提供空格以使代码可读。结合以上内容,您可以执行以下操作:

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

struct listNode {
    int data;
    struct listNode *next;
};

struct stack {
    struct listNode *top;
};

struct stack *createstk()
{
    struct stack *stk;
    stk = malloc (sizeof (struct stack));
    stk->top = NULL;
    return stk;
}

int isEmpty (struct stack *stk)
{
    return stk->top == NULL;
}

void deleteStack (struct stack *stk)
{
    struct listNode *temp, *p;
    p = stk->top;
    while (p) {
        temp = p->next;
        p = p->next;
        free (temp);
    }
    free (stk);
}

void push (struct stack *stk, int data){

    struct listNode *temp;

    temp = malloc (sizeof *temp);
    if (!temp) {
        perror ("push()-malloc-temp");
        return;
    }

    temp->data = data;
    temp->next = stk->top;
    stk->top = temp;
}

int pop(struct stack *stk){

    int data;
    struct listNode *temp;

    if (isEmpty(stk))
        return INT_MIN;

    temp = stk->top;
    data = temp->data;
    stk->top = stk->top->next;

    free (temp);

    return data;
}
int peek(struct stack *stk){
    if(isEmpty(stk))
        return INT_MIN;
    return stk->top->data;
}

int main (void) {
    int i=0;
    struct stack *stk=createstk();

    for (i = 0; i <= 10; i++)
        push(stk,i);

    printf("Top Element is %d\n",peek(stk));

    for (i = 0; i <= 10; i++)
        printf ("  popped element is %d\n",pop(stk));

    if (isEmpty(stk))
        printf ("stack is empty\n");
    else
        printf ("stack is not empty\n");

    deleteStack(stk);

    return 0;
}

使用/输出示例

$ ./bin/stack_ll
Top Element is 10
  popped element is 10
  popped element is 9
  popped element is 8
  popped element is 7
  popped element is 6
  popped element is 5
  popped element is 4
  popped element is 3
  popped element is 2
  popped element is 1
  popped element is 0
stack is empty

内存使用/错误检查

在您编写的任何动态分配内存的代码中,对于任何分配的内存块,您都有2个职责:(1)始终保留指向起始地址的指针因此,(2)当不再需要它时可以释放

当务之急是使用一个内存错误检查程序来确保您不会尝试访问内存或在已分配的块的边界之外/之外进行写入,不要试图以未初始化的值读取或基于条件跳转,最后,以确认您释放了已分配的所有内存。

对于Linux,valgrind是正常选择。每个平台都有类似的内存检查器。它们都很容易使用,只需通过它运行程序即可。

$ valgrind ./bin/stack_ll
==25935== Memcheck, a memory error detector
==25935== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25935== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==25935== Command: ./bin/stack_ll
==25935==
Top Element is 10
  popped element is 10
  popped element is 9
  popped element is 8
  popped element is 7
  popped element is 6
  popped element is 5
  popped element is 4
  popped element is 3
  popped element is 2
  popped element is 1
  popped element is 0
stack is empty
==25935==
==25935== HEAP SUMMARY:
==25935==     in use at exit: 0 bytes in 0 blocks
==25935==   total heap usage: 12 allocs, 12 frees, 184 bytes allocated
==25935==
==25935== All heap blocks were freed -- no leaks are possible
==25935==
==25935== For counts of detected and suppressed errors, rerun with: -v
==25935== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认已释放已分配的所有内存,并且没有内存错误。

如果您还有其他问题,请告诉我。