带头结点的链栈

链栈:采用链式存储的栈

链栈的优点:便于多个栈共享存储空间和提高其效率,链栈不存在栈满上溢的情况。
实现:通常采用单链表老实现。
链栈规定所有的操作都在第一个结点处(表头)进行。
这里是带头结点的链栈图示:

Lstack.h

//链栈

#define ElemType int
typedef struct Node * stack;
//结构体
typedef struct Node{
    ElemType data;   //数据域
    struct Node *next;  //指针域 
}Node,* Lstack; 


//函数声明 
Lstack InitStack();  //初始化一个栈(顺序栈为新建,与链栈不同) 
void  Push(stack p,ElemType x);  //进栈
ElemType Pop(stack p);  //出栈 
void PrintStack(stack p); //打印栈 
bool Isempty(stack p);   //判断栈空 
ElemType  GetTop(stack p);  //读栈顶元素
void ClearStack(stack p); //销毁栈 

Lstack.c

#include "Lstack.h" 

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


int main()
{
    //特别说明指针的链表的传值与传地址 
    //Lstack s 是Node *类型的,传地址的时候 Push(&s,m)是错误的 

    //这里的链栈是带头结点的链栈,不带头结点的链栈写法稍有不同 
    int n=1;
    int m; 
    Lstack s;
    s=InitStack();



    while(n!=0)
    {
         printf("\t\t/////////////////////////\n");
         printf("\t\tinput your choice \n");
         printf("\t\t1.push stack \n");
         printf("\t\t2.pop stack \n");
         printf("\t\t/////////////////////////\n");
          scanf("%d",&n);
        switch(n)
        {
            int m,p;
            case 1: printf("1.input the elem you want to push\n");
                    scanf("%d",&m);
               Push(s,m); 
               PrintStack(s);
                break;
            case 2: p=Pop(s);
                   printf("pop the numble: %d \n",p);
                    PrintStack(s);
                break;
            default:
                break;
        }
    }

    //printf("分配地址空间失败!\n"); 
    return 0;
}


Lstack InitStack() //初始化一个栈(顺序栈为新建,与链栈不同) 
{
    stack s=(stack )malloc(sizeof(Node));  //分配地址空间 
    if(s==NULL){
        printf("分配地址空间失败!\n"); 
    }  
    s->next=NULL;
    return s; 
}

void  Push(stack p,ElemType x)  //进栈
{
    Node *s =(Node *)malloc(sizeof(Node));

if(p->next==NULL)
{
    s->data=x;
    s->next =NULL;
    p->next =s; 
}else{
    s->data=x;
    s->next =p->next;
    p->next =s;
} 
    } 


void PrintStack(stack p)    //打印栈
{
        Node *list,*start;
      printf("打印链表:"); 
     if(p->next==NULL)
      {
        printf("stack is empty!:\n");
     }else{
    start = p->next;
    while (start!=0)
    {
        printf("%d ",start->data);  
        start = start->next;
    }
    printf("\n");
}

}
ElemType Pop(stack p)  //出栈 相当于链表表头删除结点 
{
    Node *m;
    if(p->next ==NULL)
    {
        printf("stack is empty");
        return NULL;
    } else{
        m=p->next;
        p->next=m->next;
        return m->data;
        free(m);
    }
} 

bool Isempty(stack p)   //判断栈空 
{
    if(p->next==NULL)return true;
    else return false;
}

ElemType  GetTop(stack p) //读栈顶元素
{
    Node *m;
    if(p->next ==NULL)
    {
        printf("stack is empty");
        return NULL;
    } else{
        m=p->next;
        return m->data;
    }
}

void ClearStack(stack p)//销毁栈 
{
    Node *l;
    for(l=p;l!=NULL;l=l->next)
    {
        free(l);
    }
}



你可能感兴趣的:(struct,存储,栈,单链表,typedef)