数据结构——栈

逻辑结构:在数据结构中栈只能在一段进行进栈和出栈操作的线性结构---所以满足后进先出的原则

物理结构:在存储结构上分为顺序栈和链栈

1.顺序栈

1.1顺序栈的结构体

cs 复制代码
#define MaxSize 10
typedef struct Stack
{
	int data[MaxSize];//数组用于存放栈中的元素
	int top;//栈顶指针
}SqStack;

1.2初始化顺序栈

cs 复制代码
//初始化栈
void InitStack(SqStack* S)
{
	S->top = -1;//栈顶指针为-1表示为空栈
}

1.3栈的判空

cs 复制代码
 //栈的判空
bool Empty(SqStack* S)
{
	if (S->top == -1)
	{
		printf(" 这个栈是空栈\n");
		return true;
	}
	else
	{
		return false;
	}
}

1.4进栈操作

cs 复制代码
//进栈操作

bool Push(SqStack* S)
{
	//进栈要先保证栈没有满
	if (S->top >= MaxSize)
	{
		return false;
	}
	int x = 0;
	printf("请输入要进栈的元素:");
	scanf("%d", &x);
	S->data[++S->top] = x;
	//S->top=S->top+1;
	// S->data[S->top]=x;
	//先对指针加一,再进行赋值操作
	return true;
}

1.5出栈操作

cs 复制代码
//出栈操作
bool Pop(SqStack* S,int* x)
{
	//出栈要保证栈不空
	if (S->top == -1)
	{
		return false;
	}
	//出栈操作只能取出栈顶元素
	*x = S->data[S->top--];
	//x=S->data[S->top];
	//s->top--;
	//这里的数据x依旧在内存当中并没有删除,只是在逻辑上删除了
	return true;
}

1.6读出栈顶元素

cs 复制代码
//读栈顶元素与出栈操作区别不大
bool GetTop(SqStack* S,int* x)
{
    //读栈顶元素要保证栈不空
    if (S->top == -1)
    {
        return false;
    }
     *x = S->data[S->top];
    return true;
}

1.7完整的顺序栈代码

cs 复制代码
//顺序栈的基本操作

typedef struct Stack
{
	int data[MaxSize];//数组用于存放栈中的元素
	int top;//栈顶指针
}SqStack;


//初始化栈
void InitStack(SqStack* S)
{
	S->top = -1;//栈顶指针为-1表示为空栈
}

 //栈的判空
bool Empty(SqStack* S)
{
	if (S->top == -1)
	{
		printf(" 这个栈是空栈\n");
		return true;
	}
	else
	{
		return false;
	}
}

//进栈操作

bool Push(SqStack* S)
{
	//进栈要先保证栈没有满
	if (S->top >= MaxSize)
	{
		return false;
	}
	int x = 0;
	printf("请输入要进栈的元素:");
	scanf("%d", &x);
	S->data[++S->top] = x;
	//S->top=S->top+1;
	// S->data[S->top]=x;
	//先对指针加一,再进行赋值操作
	return true;
}

//出栈操作
bool Pop(SqStack* S,int* x)
{
	//出栈要保证栈不空
	if (S->top == -1)
	{
		return false;
	}
	//出栈操作只能取出栈顶元素
	*x = S->data[S->top--];
	//x=S->data[S->top];
	//s->top--;
	//这里的数据x依旧在内存当中并没有删除,只是在逻辑上删除了
	return true;
}


//读栈顶元素与出栈操作区别不大
bool GetTop(SqStack* S,int* x)
{
	//读栈顶元素要保证栈不空
	if (S->top == -1)
	{
		return false;
	}
	 *x = S->data[S->top];
	return true;
}


int main()
{
	SqStack S;
	int x = 0;//用于记录栈顶元素,或者读出栈顶元素
	InitStack(&S);
	//先进栈5个元素
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		Push(&S);
	}
	//出栈一个元素
	Pop(&S,&x);
	printf("出栈元素是%d\n", x);

	//读出此时的栈顶元素
	GetTop(&S,&x);
	printf("此时的栈顶元素是%d\n", x);
	return 0;
}

2.链栈

下面主要介绍不带头结点的链栈,并且把链表的表头当作链栈的栈顶。

2.1链栈的结构体和初始化

cs 复制代码
typedef struct LinkNode
{
	int data;
	struct LinkNode* next;
}LiStack;


//初始化链栈
void InitLiStack(LiStack** L)
{
	(*L) = NULL;
}



int main()
{
	LiStack* S=NULL;
	int x = 0;
	InitLiStack(&S);//这里涉及到二级指针
	//进栈操作,先进栈五个元素
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		Push(&S);
	}
	//出栈一个元素
	Pop(&S,&x);
	printf("出栈的元素是%d\n", x);

	//获取栈顶元素
	GetTop(S,&x);
	printf("当前栈顶元素是%d\n", x);
}

2.2入栈操作

cs 复制代码
//入栈
bool Push(LiStack** L)
{
	//对于链栈不存在栈满
	int x = 0;
	printf("请输入要进栈的整数:");
	scanf("%d", &x);

	LiStack* s = (LiStack*)calloc(1, sizeof(LiStack));
	if (s == NULL)
	{
		return false;
	}
	s->data = x;
	s->next = (*L);
	(*L) = s;
	return true;
}

2.3出栈操作

cs 复制代码
//出栈
bool Pop(LiStack** L, int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = (*L)->data;
	LiStack* p = (*L);
	(*L) = p->next;
	free(p);
	return true;
}

2.4读出栈顶元素

cs 复制代码
//获取栈顶元素
bool GetTop(LiStack* L,int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = L->data;
	return true;
}

2.5链栈的整体代码

cs 复制代码
//不带头结点的链栈

typedef struct LinkNode
{
	int data;
	struct LinkNode* next;
}LiStack;


//初始化链栈
void InitLiStack(LiStack** L)
//这里涉及到二级指针
{
	(*L) = NULL;
}

//入栈
bool Push(LiStack** L)
{
	//对于链栈不存在栈满
	int x = 0;
	printf("请输入要进栈的整数:");
	scanf("%d", &x);

	LiStack* s = (LiStack*)calloc(1, sizeof(LiStack));
	if (s == NULL)
	{
		return false;
	}
	s->data = x;
	s->next = (*L);
	(*L) = s;
	return true;
}

//出栈
bool Pop(LiStack** L, int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = (*L)->data;
	LiStack* p = (*L);
	(*L) = p->next;
	free(p);
	return true;
}

//获取栈顶元素
bool GetTop(LiStack* L,int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = L->data;
	return true;
}

int main()
{
	LiStack* S=NULL;
	int x = 0;
	InitLiStack(&S);//这里涉及到二级指针,传递的是栈顶指针的地址
	//进栈操作,先进栈五个元素
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		Push(&S);
	}
	//出栈一个元素
	Pop(&S,&x);
	printf("出栈的元素是%d\n", x);

	//获取栈顶元素
	GetTop(S,&x);
	printf("当前栈顶元素是%d\n", x);
}
相关推荐
郝学胜-神的一滴3 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
不知名XL9 小时前
day50 单调栈
数据结构·算法·leetcode
cpp_250111 小时前
P10570 [JRKSJ R8] 网球
数据结构·c++·算法·题解
cpp_250111 小时前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷
季明洵11 小时前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
only-qi11 小时前
leetcode19. 删除链表的倒数第N个节点
数据结构·链表
cpp_250111 小时前
P9586 「MXOI Round 2」游戏
数据结构·c++·算法·题解·洛谷
浅念-11 小时前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
爱吃生蚝的于勒12 小时前
【Linux】进程信号之捕捉(三)
linux·运维·服务器·c语言·数据结构·c++·学习
数智工坊13 小时前
【数据结构-树与二叉树】4.6 树与森林的存储-转化-遍历
数据结构