定义:栈是限定在表尾进行插入和删除操作的线性表

允许插入和删除的一段称为栈顶(top),另一端称为栈底(top)。栈是后进先出(Last In First Out)的线性表,简称LIFO结构。

一、顺序栈

当栈存在一个元素时,top等于0,因此通常把栈空的判定条件设定为top=-1。

顺序栈的动态数组实现:

//顺序栈,动态数组实现,感觉用的较少。和静态数组基本一样
#include<stdio.h>
 
#define true 1
#define false 0
#define STACK_INIT_SIZE 20
typedef int bool;
 
typedef struct SequenceStack
{
	int *data;
	int top;//用于栈顶指针。当栈为空时top=-1,栈满时top=MAXSIZE-1
}SqStack;
 
//初始化栈
bool InitStack(SqStack *s)
{
	s->data = (int*)malloc(sizeof(int)*STACK_INIT_SIZE);
	if (!s->data)
		exit(-1);
	s->top = -1;
	return 1;
}
 
//栈空判断,空返回1,非空返回0
bool StackEmpty(SqStack *s)
{
	if (s->top == -1)
		return true;
	else
		return false;
}
 
//栈的长度
int StackLength(SqStack *s)
{
	return s->top + 1;
}
 
//返回栈顶元素
bool StackGetTop(SqStack *s, int *val)
{
	if (s->top == -1)
		return false;
	*val = s->data[s->top];
	return true;
}
 
//入栈
//入栈时判断栈满
bool Push(SqStack *s, int val)
{
	if (s->top == STACK_INIT_SIZE - 1)
		return false;
	s->top++;
	s->data[s->top] = val;
	return true;
 
}
 
 
//出栈
//出栈,判断栈空
bool Pop(SqStack *s, int *val)
{
	if (s->top == -1)
		return false;
	*val = s->data[s->top];
	s->top--;
	return true;
}
 
//清栈
void StackClear(SqStack *s)
{
	
	s->top = -1;
}
 
//销毁栈
void StackDestroy(SqStack *s)
{
	free(s->data);
	s->data = NULL;
	s->top = -1;
}
 
//遍历栈
void StackTraverse(SqStack *s)
{
	for (int i = 0; i <= s->top; i++)
	{
		printf("%d ", s->data[i]);
	}
	printf("\n");
}
 
int main(void)
{
	SqStack s;
	//初始化栈
	InitStack(&s);
	//初始化栈之后,判断栈是否为空
	printf("初始化栈之后,判断栈是否为空:%d\n", StackEmpty(&s));
	printf("初始化栈之后,求栈的长度\:%d\n", StackLength(&s));
	//入栈几个元素
	Push(&s, 4);
	Push(&s, 1);
	Push(&s, 7);
	Push(&s, 2);
	//遍历栈
	printf("入栈之后,遍历栈\n");
	StackTraverse(&s);
	//出栈
	int val;
	Pop(&s, &val);
	printf("出栈元素为:%d\n", val);
	//遍历栈
	printf("出栈之后,遍历栈\n");
	StackTraverse(&s);
	//判断栈是否为为空
	printf("栈空否?%d\n", StackEmpty(&s));
	printf("栈长:%d\n", StackLength(&s));
	//获取栈顶元素
	StackGetTop(&s, &val);
	printf("栈顶元素为:%d\n", val);
	//清栈
	StackClear(&s);
	printf("清栈之后,栈空否?%d\n", StackEmpty(&s));
	return 0;
}


顺序栈的静态数组实现:

//栈的顺序存储结构,静态数组实现。感觉用的较多
#include<stdio.h>
 
#define true 1
#define false 0
#define MAXSIZE 20
typedef int bool;
 
typedef struct SequenceStack
{
	int data[MAXSIZE];
	int top;//用于栈顶指针。当栈为空时top=-1,栈满时top=MAXSIZE-1
}SqStack;
 
//初始化栈
bool InitStack(SqStack *s)
{
	s->top = -1;
	return 1;
}
 
//栈空判断,空返回1,非空返回0
bool StackEmpty(SqStack *s)
{
	if (s->top == -1)
		return true;
	else
		return false;
}
 
//栈的长度
int StackLength(SqStack *s)
{
	return s->top + 1;
}
 
//返回栈顶元素
bool StackGetTop(SqStack *s, int *val)
{
	if (s->top == -1)
		return false;
	*val = s->data[s->top];
	return true;
}
 
//入栈
//入栈时判断栈满
bool Push(SqStack *s, int val)
{
	if (s->top == MAXSIZE - 1)
		return false;
	s->top++;
	s->data[s->top] = val;
	return true;
 
}
 
 
//出栈
//出栈,判断栈空
bool Pop(SqStack *s, int *val)
{
	if (s->top == -1)
		return false;
	*val = s->data[s->top];
	s->top--;
	return true;
}
 
//清栈
void StackClear(SqStack *s)
{
	s->top = -1;
}
 
//遍历栈
void StackTraverse(SqStack *s)
{
	for (int i = 0; i <= s->top; i++)
	{
		printf("%d ", s->data[i]);
	}
	printf("\n");
}
 
int main(void)
{
	SqStack s;
	//初始化栈
	InitStack(&s);
	//初始化栈之后,判断栈是否为空
	printf("初始化栈之后,判断栈是否为空:%d\n", StackEmpty(&s));
	printf("初始化栈之后,求栈的长度\:%d\n", StackLength(&s));
	//入栈几个元素
	Push(&s, 4);
	Push(&s, 1);
	Push(&s, 7);
	Push(&s, 2);
	//遍历栈
	printf("入栈之后,遍历栈\n");
	StackTraverse(&s);
	//出栈
	int val;
	Pop(&s, &val);
	printf("出栈元素为:%d\n", val);
	//遍历栈
	printf("出栈之后,遍历栈\n");
	StackTraverse(&s);
	//判断栈是否为为空
	printf("栈空否?%d\n", StackEmpty(&s));
	printf("栈长:%d\n", StackLength(&s));
	//获取栈顶元素
	StackGetTop(&s, &val);
	printf("栈顶元素为:%d\n", val);
	//清栈
	StackClear(&s);
	printf("清栈之后,栈空否?%d\n", StackEmpty(&s));
	return 0;
}


二、链栈

在链栈中,一般不需要头结点,用top指针代替了链表中的头指针。注意链栈中元素之间指针的指向,跟链表是反过来的。

入栈:

对于链栈的入栈push操作,假设要入栈结点为s,元素值为e,top为栈顶指针。

出栈:

出栈p结点。

示意图:


链栈实现:

//栈,不带头结点
 
#include<stdio.h>
 
#define true 1
#define false 0
typedef int bool;
 
typedef struct StackNode
{
	int data;
	struct node *next;
}StackNode,*PStackNode;
 
typedef struct LinkStack
{
	int count;
	PStackNode top;
}LinkStack,*PLinkStack;
 
//初始化栈,成功返回1,失败返回0
void InitStack(PLinkStack s)
{
	s->top = NULL;
	s->count = 0;
	return;
}
 
//入栈,成功返回1,失败返回0
bool Push(PLinkStack s,int val)
{
	PStackNode pNew = (PStackNode)malloc(sizeof(StackNode));
	if (pNew == NULL)
	{
		return 0;
	}
	pNew->data = val;
	pNew->next = s->top;
	s->top = pNew;
	s->count++;
	return 1;
}
 
//出栈,成功返回1,失败返回0
bool Pop(PLinkStack s, int *val)
{
	if (s->top == NULL)
	{
		return 0;//栈空,出栈失败
	}
	PStackNode p = s->top;
	*val = s->top->data;
	s->top = s->top->next;
	free(p);
	s->count--;
	return 1;
}
 
//遍历
void StackTraverse(PLinkStack s)
{
	PStackNode p = (PStackNode)malloc(sizeof(StackNode));
	p = s->top;
	while (p)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}
 
 
//获取栈顶元素
bool GetTop(PLinkStack s, int *val)
{
	if (s->top == NULL)
	{
		return 0;
	}
	*val = s->top->data;
	return 1;
}
 
//栈空判断
bool StackEmpty(PLinkStack s)
{
	if (s->top == NULL)
		return 1;
	else
		return 0;
}
 
//栈长
int StackLength(PLinkStack s)
{
	return s->count;
}
 
//清栈
void ClearStack(PLinkStack s)
{
	PStackNode p = s->top;
	while (p)
	{
		s->top = p->next;
		free(p);
		p = s->top;
 
	}
	s->count = 0;
}
 
 
int main(void)
{
	LinkStack s;
	//初始化栈
	InitStack(&s);
	//初始化栈之后,判断栈是否为空
	printf("初始化栈之后,判断栈是否为空:%d\n", StackEmpty(&s));
	//入栈
	Push(&s, 1);
	Push(&s, 2);
	Push(&s, 3);
	Push(&s, 4);
	//遍历栈
	printf("入栈之后,遍历栈:\n");
	StackTraverse(&s);
	//入栈之后,判断栈是否为空
	printf("入栈之后,判断栈是否为空:%d\n", StackEmpty(&s));
	//出栈
	int val;
	Pop(&s, &val);
	printf("出栈之后,遍历栈:\n");
	StackTraverse(&s);
	printf("出栈元素值为:%d\n", val);
	//求栈的长度
	printf("栈长:%d\n", StackLength(&s));
	//清栈
	ClearStack(&s);
	printf("清栈之后,判断栈是否为空:%d\n", StackEmpty(&s));
 
	return 0;
}

三、两栈共享空间

初始化:top=-1,top2=MAXSIZE;

//两栈共享空间,top1为栈1栈顶指针,初始化为-1;top2为栈2栈顶指针,初始化为MAXSIZE

#include<stdio.h>

typedef int bool;

#define true 1
#define false 0

#define MAXSIZE 100

typedef struct
{
	int data[MAXSIZE];
	int top1, top2;
}SqDoubleStack;

//初始化栈,top1=-1,top2=MAXSIZE
void InitStack(SqDoubleStack *s)
{
	s->top1 = -1;
	s->top2 = MAXSIZE;
}

//判断栈是否为空,是返回true,不是返回false,栈为空时top1==-1并且top2==MAXSIZE
bool StackEmpty(SqDoubleStack *s)
{
	if (s->top1 == -1 && s->top2 == MAXSIZE)
		return true;
	else
		return false;
}

//栈满
bool StackFull(SqDoubleStack *s)
{
	return s->top1 + 1 == s->top2;
}

//求栈的长度
int StackLength(SqDoubleStack *s)
{
	return s->top1 + 1 + MAXSIZE - s->top2;
}

//入栈,flag表示入栈1还是栈2
bool Push(SqDoubleStack *s, int flag, int key)
{
	//判断栈满
	if (s->top1 + 1 == s->top2)
		return false;
	if (flag == 1)
	{
		s->data[++s->top1] = key;
		return true;
	}
	else if (flag == 2)
	{
		s->data[--s->top2] = key;
		return true;
	}
	return false;//flag等于其他数
}

//出栈
bool Pop(SqDoubleStack *s, int flag, int *key)
{
	//栈1出栈
	if (flag == 1)
	{
		if (s->top1 == -1)
			return false;
		*key = s->data[s->top1--];
		return true;
	}
	else if (flag == 2)
	{
		if (s->top2 == MAXSIZE)
			return false;
		*key = s->data[s->top2++];
		return true;
	}
	return false;
}

//遍历栈
void StackTraverse(SqDoubleStack *s)
{
	for (int i = 0; i <= s->top1; i++)
		printf("%d ", s->data[i]);
	for (int j = s->top2; j <= MAXSIZE - 1; j++)
		printf("%d ", s->data[j]);
	printf("\n");
}


int main(void)
{
	SqDoubleStack s;
	InitStack(&s);
	printf("初始化栈后,栈是否为空:%d\n", StackEmpty(&s));
	printf("给栈1入几个元素\n");
	Push(&s, 1, 10);
	Push(&s, 1, 20);
	Push(&s, 1, 30);
	printf("给栈2入几个元素:\n");
	Push(&s, 2, 100);
	Push(&s, 2, 200);
	Push(&s, 2, 300);
	printf("遍历栈:\n");
	StackTraverse(&s);
	printf("栈长度为:%d\n", StackLength(&s));
	printf("栈1出栈\n");
	int key;
	Pop(&s, 1, &key);
	printf("出栈元素为:%d\n", key);
	printf("栈2出栈\n");
	Pop(&s, 2, &key);
	printf("出栈元素为:%d\n", key);
	printf("遍历栈:\n");
	StackTraverse(&s);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值