C语言数据结构拦路虎(七)-栈

栈(stack),先进后出(Last In First Out)LIFO

其实就当做一个容器,如篮子,箱子,瓶子。放东西进去,先放的在瓶底,最后拿出来。后放的在瓶口,先取出来。

(一)顺序栈

先看定义吧

typedef int datatype	//栈的数据类型
#define maxsize 64		//栈的大小

typedef struct
{
	datatype data[maxsize];
	int top;			//栈顶指针,其实就是栈里存了多少东西
}seqstack;

其实就是一个结构体里,成员是数组,我们通过结构体指针,来操作内存数据。

data[]里面存数据,

top做指标,好像一个浮标,涨到哪里了。这里需要着重理解一下,因为后面还有队列,它有两个指标front和rear。我认为top,front,rear,不能称为指针,是C语言意义上的指针,它们只是一个标记,我想称为指标,不要让指针把你吓跑了。

其实这个top指标是认为加在data数组上的,使它们相关联,我们通过top等于多少,知道这个栈是空的如:top=-1,用了多少,如:top=63,说明满栈了。top是人为加的,你也可以在函数里改。这里只不过要满足栈的定义先进后出,我们需要知道栈顶处于什么状态,举例使用:

建栈:

    seqstack *p; //创建一个栈
    p=(seqstack*)malloc(maxsize*sizeof(seqstack));//给它分配空间
    p->top=-1;//标记一下,它是空的

我需要加一个元素入栈,如 5,

        s->top++;//把标记s->top+1=0,说明有一个元素
        s->data[s->top]=5;//把数据存进去,s->data[0]=5

再加一个 8

        s->top++;//把标记s->top+1=1,说明有一个元素
        s->data[s->top]=8;//把数据存进去,s->data[1]=5

一直加,直到s->top==63,那s->data[63].数组是不是已经满了,数组下标从0开始,从结构体定义知道它最大能存64个,也就是最大到s->top[63]。但电脑不会告诉你啊,你需要读取特征啊,特征就是s->top==63,说明已经满栈了。

 

前面已经知道,指针其实是带有指向性的地址,它的值是一个地址,而且是一个首地址,你可以通过这个首地址,来操作数据

 data下标从0开始,最多能到63

栈顶指针从-1开始     -1为空      >0为非空

操作函数

stack.c

//创建一个空栈
seqstack * Creat_stack()
{
	seqstack *p; //创建一个栈
	p=(seqstack*)malloc(maxsize*sizeof(seqstack));
	p->top=-1;
	return p;
}

//置栈空
status Setnull(seqstack *s)
{
	s->top=-1;
	return TRUE;
}

//判栈空
status Empty(seqstack *s)
{
	if(s->top>0)
		return FALSE;
	else
		return TRUE;
}

//进栈
//首先判断栈是否满了
status Push(seqstack *s,int x)
{
	if(s->top==maxsize-1)
	{
		printf("overflow");
		return FALSE;
	}

	else
	{
		s->top++;
		s->data[s->top]=x;
	}
	return TRUE;
}

//退栈
//首先判断栈是否空了,返回被删值
status Pop(seqstack *s)
{
	if(Empty(s))
	{
		printf("underflow");
		return FALSE;
	}

	else
	{
		s->top--;
		return s->data[s->top+1];
	}
}

//取栈顶
//首先判断栈是否空了,返回栈顶值
status Pop(seqstack *s)
{
	if(Empty(s))
	{
		printf("stack is empty");
		return FALSE;
	}

	else
	{
		return s->data[s->top];
	}
}

stack.h

typedef int datatype;	//栈的数据类型

#define status		int //函数状态
#define TRUE		1
#define FALSE		0

#define maxsize 64		//栈的大小

typedef struct stack
{
	datatype data[maxsize];
	int top;			//栈顶指针,其实就是栈里存了多少东西
}seqstack;

//创建一个栈
seqstack * Creat_stack();
//置栈空
status Setnull(seqstack *s);
//判栈空
status Empty(seqstack *s);
//进栈
//首先判断栈是否满了
status Push(seqstack *s,int x);
//退栈
//首先判断栈是否空了,返回被删值
status Pop(seqstack *s);
//取栈顶
//首先判断栈是否空了,返回栈顶值
status Pop(seqstack *s);

main.c

#include<stdio.h>
#include"stack.h"

int main()
{
	int i=0;
	//打算创建两个栈,p,q
	seqstack *q;
	//创建第一个栈q
	q=Creat_stack();
	for(i=0;i<maxsize;i++)
	{
		//把3入q栈,并打印OK
		if(Push(q,3))
			printf("OK\n");
	}

	return TRUE;
}

观察地址和内存的分配

栈q首地址 0x00242f20

64个int类型数据数组data,256字节+1个int类型top,4字节

int 4个字节,4个地址,64+1=65个int,65x4=260字节,260地址

首地址即数据data的首地址

top的地址,243020-242f20=256

top四个字节,它的地址是,首地址+260-4(同一为十六进制)=242f20+104-4=243020

栈空间的尾地址是 243024

 

(二)链栈

不要恋战,。。。。。。。。。

如果前面顺序栈,都能理解这里链栈,那就是链了,单链表的链。但这个单链表要满足LIFO,就是给它加上限制而已。

然后既然是单链表,则没有个数的限制,动态产生的。malloc函数。

先看定义吧

typedef struct node
{
	datatype data;
	struct node *next;
}Linklist;

Linklist *top;

我把它归到了单链表里。只不过是头插法的单链表,尾结点指向空。top做栈顶指针,也是栈的入口。

当top==NULL说明空栈。

实现以下建栈,入栈出栈

//链栈建栈,入栈与出栈

//建栈(栈顶指针是结点的指针域,如果为NULL,则为空栈)
//采用头插法建立链栈,其实就是单链表
//建立一个结点存入数据,指针域指向空结点
//返回栈顶指针 
Linklist * creat_linkstack(int x)
{
	//p为数据结点,top栈顶指针
	Linklist *p,*top;
	top=NULL;
	p=(Linklist *)malloc(sizeof(Linklist));//生成新节点

	p->data=x;
	p->next=top; //指向空结点

	return p; //返回栈顶指针 
}

//入栈
Linklist * pushlstack(Linklist * s,int x)
{
	Linklist *p;

	p=(Linklist *)malloc(sizeof(Linklist));//生成新节点

	p->data=x;
	p->next=s;//新节点指向原结点

	return p;
}

//出栈
Linklist * poplstack(Linklist * s)
{
	Linklist * p;
	if(s->next==NULL)
	{
		printf("under flow");
		return NULL;
	}

	else
	{
	  p=s->next;//指向下一个节点
	  free(s);//
	  return p;
	}
}

验证OK

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值