数据结构栈

  1. 什么是栈?

只能在一端进行插入和删除操作的线性表(又称为堆栈),进行插入和删除操作的一端称为栈顶,另一端称为栈底

2. 栈特点

先进后出 FILO first in last out FILO

顺序栈

1)逻辑结构:线性结构

2)存储结构:顺序存储

3)操作:入栈、出栈

typedef struct seqstack

{

int * data;

int maxlen;

int top;

}seqstack_t;

1)创建一个空的栈

2)入栈

判满

移动栈针

将数据入栈

3)出栈

判空

移动栈针

将数据出栈

#ifndef _SEQSTACK_H_
#define _SEQSTACK_H_

typedef struct seqstack
{
	int* data;//指向栈的存储位置
	int maxlen;//保存栈的最大长度
	int top;//称为栈针,用的时候,心里面可以将按照顺序表里的last来使用
			//top 始终代表当前栈内最后一个有效元素的下标
}seqstack_t;
//1.创建一个空的栈
seqstack_t *CreateEpSeqStack(int len);//len代表的是创建栈的时候的最大长度
//2.判断是否为满,满返回1 未满返回0
int	 IsFullSeqStack(seqstack_t *p);
//3.入栈 
int  PushStack(seqstack_t *p, int data);//data代表入栈的数据
//4.判断栈是否为空
int IsEpSeqStack(seqstack_t *p);
//5.出栈 
int PopSeqStack(seqstack_t *p);
//6. 清空栈 
void ClearSeqStack(seqstack_t *p);
//7. 获取栈顶数据(注意不是出栈操作,如果出栈,相当于删除了栈顶数据,只是将栈顶的数据获取到,不需要移动栈针)
int GetTopSeqStack(seqstack_t *p);
//8. 求栈的长度
int LengthSeqStack(seqstack_t *p);
			#endif 

链式栈

  1. 逻辑结构线性结构
  2. 存储结构链式存储
  3. 操作入栈出栈

#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_

//入栈和出栈只在第一个节点位置操作
typedef int datatype;
typedef struct linkstack
{
	datatype data;//数据域
	struct linkstack *next;//指针域
}linkstack_t;
//1.创建一个空的栈
void CreateEpLinkStack(linkstack_t **ptop);
//2.入栈   data是入栈的数据
参数上之所以采用二级指针,因为我们要随着入栈添加新的节点作为头,top需要永远指向当前链表的头,
那么修改main函数中的top,我们采用地址传递
int PushLinkStack(linkstack_t **ptop, datatype data);
//3.判断栈是否为空
int IsEpLinkStack(linkstack_t *top);
//4.出栈
datatype PopLinkStack(linkstack_t **ptop);
//5.清空栈
void ClearLinkStack(linkstack_t **ptop);//用二级指针,是因为清空后需要将main函数中的top变为NULL
//6.求栈的长度
int LengthLinkStack(linkstack_t *top);//用一级指针,是因为我只是求长度,不需要修改main函数中top指针的指向
//7.获取栈顶数据,不是出栈,不需要移动main函数中的top,所以用一级指针
datatype GetTopLinkStack(linkstack_t *top);
#endif

linkstack.c

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

//入栈和出栈只在第一个节点位置操作
typedef int datatype;
typedef struct linkstack
{
	datatype data;//数据域
	struct linkstack *next;//指针域
}linkstack_t;
//1.创建一个空的栈
void CreateEpLinkStack(linkstack_t **ptop)//*ptop == top
{
    *ptop = NULL;
}
//2.入栈   data是入栈的数据
// 参数上之所以采用二级指针,因为我们要随着入栈添加新的节点作为头,top需要永远指向当前链表的头,
// 那么修改main函数中的top,我们采用地址传递
int PushLinkStack(linkstack_t **ptop, datatype data)
{
    //1.开辟空间存数据并初始化
    linkstack_t * pnew = (linkstack_t *)malloc(sizeof(linkstack_t));
    if(pnew == NULL)
    {
        perror("PushLinkStack err");
        return -1;
    }
    pnew->data = data;
    pnew->next = NULL;
    //2.将新节点插入无头单向链表中作为第一个节点
    pnew->next = *ptop;
    //3.移动栈针
    *ptop = pnew;
    return 0;
}
//3.判断栈是否为空
int IsEpLinkStack(linkstack_t *top)
{
    return top == NULL;
}
//4.出栈
datatype PopLinkStack(linkstack_t **ptop)
{
    //0.容错判断,判空
    if(IsEpLinkStack(*ptop))
    {
        perror("PopLinkStack err");
        return -1;
    }
    //1.定义pdel指向被删除节点
    linkstack_t *pdel = *ptop;
    //2.定义一个变量temp保存出栈数据
    datatype temp = pdel->data;
    //3.移动栈针
    *ptop = pdel->next;
    //4.释放被删除节点
    free(pdel);
    pdel =NULL;
    //5.返回数据
    return temp;
}
//5.清空栈
void ClearLinkStack(linkstack_t **ptop)//用二级指针,是因为清空后需要将main函数中的top变为NULL
{
    //只要不为空就出栈
    while (!IsEpLinkStack(*ptop))
        PopLinkStack(ptop);
    
}
//6.求栈的长度
int LengthLinkStack(linkstack_t *top)//用一级指针,是因为我只是求长度,不需要修改main函数中top指针的指向
{
    //遍历无头单向链表,求长度
    int len = 0;
    while (top != NULL)
    {
        len++;
        top=top->next;
    }
    return len;
}
//7.获取栈顶数据,不是出栈,不需要移动main函数中的top,所以用一级指针
datatype GetTopLinkStack(linkstack_t *top)
{
    // 只要不为空就返回数据
    if(!IsEpLinkStack(top))
        return top->data;
    return -1;
}
int main(int argc, char const *argv[])
{
    // linkstack_t *top = NULL;
    linkstack_t *top;
    CreateEpLinkStack(&top);
    for(int i=1;i<=5;i++)
        PushLinkStack(&top,i);
    printf("top value is %d\n",GetTopLinkStack(top));//5
    printf("len is %d \n",LengthLinkStack(top));//5
    while (!IsEpLinkStack(top))
        printf("%d ",PopLinkStack(&top));//5 4 3 2 1
    printf("\n");

    return 0;
}

总结:

顺序栈和链式栈的区别是什么?

(1)存储结构不同,顺序栈相当于数组,连续的,链式栈 链表非连续的

  1. 顺序栈的长度受限制,而链栈不会
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值