目录
Ⅱ)采用链式存储结构实现——链栈-->基于单链表(带头结点)
栈
栈的定义
之允许在一端进行插入和删除的线性表
栈的性质
先进后出
栈的应用场景
1.函数调用的实现
2.倒着走的逻辑:如历史记录、撤销等
3.内存中的堆栈
4.STL库中的stack
存储结构:
Ⅰ)采用顺序存储结构实现——顺序栈
比如我们申请一个十个大小的int数组,并随机存储一些数据
#define maxsize 10
这里需要注意:有时候为了方便描述,通常会借用“指针”两个字来称呼那个用于标记的变量
初始化:top=-1;栈顶我们用top指针指示(注意这里的指针不是真的指针),初始化时top=-1
Stack initStack(){
Stack s;
s.data = (int*)malloc(sizeof(int) * maxsize);
if (s.data == NULL) {
printf("空间分配失败\n");
}
s.top = -1;
return s;
}
入栈:top++;a[top]=k//或者写成a[++top]=k;
void Push(Stack* s, int k) {
if (isFull(s) == 1) {
printf("栈满");
}
else {
s->top++;
s->data[s->top] = k;
}
}
出栈:top--;//top--之前的数据在出栈后会变成脏数据,所以不需要理会
void Pop(Stack* s) {
if (isEmpty(s) == 1)
{
printf("栈空,不能出栈\n");
}
else
{
s->top--;
}
}
判满:top==maxsize-1;的时候栈满
int isFull(Stack* s) {
if (s->top == maxsize - 1) {
return 1;
}
return 0;
}
判空:top==-1;top指向-1
int isEmpty(Stack* s)
{
if (s->top == -1)
{
return 1;
}
return 0;
}
获取栈顶数据:x = a[top];
int getTop(Stack s)
{
if (isEmpty(&s) == 1)
{
printf("栈空,没有数据\n");
return -1;//特殊值
}
return s.data[s.top];
}
整体代码示例:
#include<stdlib.h>
#include<stdio.h>
#define maxsize 10
typedef struct {
int* data;
int top;
}Stack;
Stack initStack(){
Stack s;
s.data = (int*)malloc(sizeof(int) * maxsize);
if (s.data == NULL) {
printf("空间分配失败\n");
}
s.top = -1;
return s;
}
int isFull(Stack* s) {
if (s->top == maxsize - 1) {
return 1;
}
return 0;
}
void Push(Stack* s, int k) {
if (isFull(s) == 1) {
printf("栈满");
}
else {
s->top++;
s->data[s->top] = k;
}
}
int isEmpty(Stack* s)
{
if (s->top == -1)
{
return 1;
}
return 0;
}
void Pop(Stack* s) {
if (isEmpty(s) == 1)
{
printf("栈空,不能出栈\n");
}
else
{
s->top--;
}
}
int getTop(Stack s)
{
if (isEmpty(&s) == 1)
{
printf("栈空,没有数据\n");
return -1;//特殊值
}
return s.data[s.top];
}
int main() {
Stack s= initStack();
printf("%d\n", getTop(s));
Push(&s, 1);
printf("%d\n", getTop(s));
Push(&s, 2);
printf("%d\n", getTop(s));
Push(&s, 3);
printf("%d\n", getTop(s));
Pop(&s);
printf("%d\n", getTop(s));
}
初始化:top=0;//这个时候top标记的时真正的栈顶元素的上面一个位置
入栈:a[top]=k;top++;//或者写成a[top++]=k;
出栈:top--;
判满:top==maxsize;的时候栈满
判空:top==0;top指向0
获取栈顶数据:x = a[top-1];
Ⅱ)采用链式存储结构实现——链栈-->基于单链表(带头结点)
初始化:初始化一个带头结点的空链表
入栈:直接用头插法,则栈顶一直时首元结点,就直接用头指针做栈顶指针
linkstack initstack()
{
linkstack s = (StackNode*)malloc(sizeof(StackNode));
if (s == NULL)
{
printf("空间分配失败\n");
}
s->next = NULL;
return s;
}
删除:删除首元结点
linkstack Pop(linkstack top)
{//出栈 删除首元节点
if (isEmpty(top) == 1)
{
printf("栈空,不能出栈\n");
}
else
{
StackNode* p = top->next;
top->next = p->next;
free(p);
p = NULL;
}
return top;
}
判满:链表不需要判满
判空:L->next==NULL;
int isEmpty(linkstack top)
{
if (top->next == NULL)
{
return 1;
}
return 0;
}
整体代码示例:
#include<stdio.h>
#include<stdio.h>
#include<stdlib.h>
#define maxsize 10
//链栈---基于带头结点的单链表实现
typedef struct StackNode {
int data;
struct StackNode* next;
}StackNode, * linkstack;
linkstack initstack()
{
linkstack s = (StackNode*)malloc(sizeof(StackNode));
if (s == NULL)
{
printf("空间分配失败\n");
}
s->next = NULL;
return s;
}
linkstack Push(linkstack top, int k)
{//入栈 头插法
linkstack s = (StackNode*)malloc(sizeof(StackNode));
if (s == NULL)
{
printf("空间分配失败\n");
return top;
}
s->data = k;
s->next = top->next;
top->next = s;
return top;
}
int isEmpty(linkstack top)
{
if (top->next == NULL)
{
return 1;
}
return 0;
}
linkstack Pop(linkstack top)
{//出栈 删除首元节点
if (isEmpty(top) == 1)
{
printf("栈空,不能出栈\n");
}
else
{
StackNode* p = top->next;
top->next = p->next;
free(p);
p = NULL;
}
return top;
}
int getTop(linkstack top)
{
if (isEmpty(top) == 1)
{
printf("栈空,没有数据\n");
return -1;//特殊值
}
else
{
return top->next->data;
}
}
int main()
{
linkstack top = initstack();
top = Push(top, 1);
printf("%d\n", getTop(top));
top = Push(top, 2);
top = Push(top, 3);
printf("%d\n", getTop(top));
top = Pop(top);
printf("%d\n", getTop(top));
return 0;
}