带头结点的链栈

链栈:采用链式存储的栈

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

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



  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
头结点链栈具体操作如下: 1. 初始化链栈:创建一个头结点,并将头结点的next指针指向NULL。 2. 入操作:在头结点后插入一个新节点,将新节点的数据域设置为要插入的元素,将新节点的next指针指向原来的第一个节点,然后将头结点的next指针指向新节点。 3. 出操作:将头结点的next指针指向的节点删除,并返回该节点的数据域作为出的元素。 4. 判断空:判断头结点的next指针是否为NULL,如果是则空,否则非空。 5. 销毁链栈:从头结点的next指针开始,依次释放每个节点的内存空间,最后释放头结点的内存空间。 不头结点链栈具体操作如下: 1. 初始化链栈:将链栈设置为NULL。 2. 入操作:如果链栈为空,特殊处理,创建一个新节点,并将新节点的数据域设置为要插入的元素,将新节点的next指针指向NULL,然后将链栈指向新节点;如果链栈不为空,创建一个新节点,并将新节点的数据域设置为链栈的数据域,将链栈的数据域设置为要插入的元素,将新节点的next指针指向链栈的next指针,然后将链栈的next指针指向新节点。 3. 出操作:将链栈指向的节点删除,并返回该节点的数据域作为出的元素。 4. 判断空:判断链栈是否为NULL,如果是则空,否则非空。 5. 销毁链栈:从链栈开始,依次释放每个节点的内存空间。 #### 引用[.reference_title] - *1* *2* *3* [使用C语言实现链栈头结点和不头结点)](https://blog.csdn.net/Keep_Trying_Go/article/details/126284714)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值