目录
- 一、栈的概念
- 二、入栈
-
- 入栈的概念
-
- 入栈的步骤
-
- 三、出栈
-
- 出栈的概念
-
- 出栈的步骤
-
- 四、获取栈顶元素
一、栈的概念
栈是仅限在表尾部进行插入和删除的线性表,遵循后进先出的原则。栈可以类比为一叠盘子,只能访问顶部盘子,而添加或者删除盘子只能从顶部开始。在计算机科学中,栈通常用于实现函数调用、递归、表达式求值等操作。我们一般可以用顺序表或者链表来实现栈。
二、入栈
- 入栈的概念
栈元素的插入操作叫做入栈,直接将元素添加到栈顶部。
-
入栈的步骤
-
将元素压入栈中,并将栈指针或索引指向新的栈顶元素。
-
栈的大小加一,顶部元素为刚刚入栈的元素。
三、出栈
- 出栈的概念
栈元素的删除操作叫做出栈,直接将顶部元素删除即可。
-
出栈的步骤
-
将栈顶的元素删除,并将栈指针或索引指向新的栈顶元素。
-
栈的大小减一
四、代码实现
1.顺序表实现
#include <stdio.h>
#include <stdlib.h>
#define eleType int
typedef struct {
eleType* elements;
size_t size; // 栈的当前大小
size_t capacity; // 栈的容量
} Stack;
// 初始化栈
void StackCreate(Stack* stk) {
stk->elements = (eleType *)malloc(sizeof(eleType) * 8);
if (stk->elements == NULL) {
printf("内存分配失败\n");
exit(1);
}
stk->size = 0;
stk->capacity = 8; // 初始栈容量为8
}
// 销毁栈
void StackDestroy(Stack* stk) {
free(stk->elements);
stk->elements = NULL;
stk->size = 0;
stk->capacity = 0;
}
// 扩容
void StackResize(Stack* stk) {
eleType* newelements = (eleType*)realloc(stk->elements, sizeof(eleType) * stk->capacity * 2);// 重新分配空间
if (newelements == NULL) {
printf("内存重新分配失败\n");
exit(1);
}
stk->capacity *= 2; // 为原来的俩倍
stk->elements = newelements;
}
// 压入元素
void StackPush(Stack* stk, eleType element) {
if (stk->capacity == stk->size) { // 如果满栈扩容
StackResize(stk);
}
stk->elements[stk->size++] = element;
}
// 弹出元素
eleType StackPop(Stack* stk) {
if (stk->size == 0) {
printf("栈元素不够\n");
exit(1);
}
return stk->elements[--stk->size]; // 弹出并且栈大小减一
}
// 栈顶元素
eleType StackTop(Stack* stk) {
if (stk->size == 0) {
printf("空栈\n");
exit(1);
}
return stk->elements[stk->size - 1]; // 获得栈顶元素
}
// 获取栈的大小
int StackGetsize(Stack* stk) {
return stk->size;
}
int main() {
Stack stk;
StackCreate(&stk);
StackPush(&stk, 10);
StackPush(&stk, 20);
StackPush(&stk, 30);
printf("top is %d\n", StackTop(&stk));
printf("pop is %d\n", StackPop(&stk));
printf("size is %d\n", StackGetsize(&stk));
StackDestroy(&stk);
}
2.链表实现
#include<stdio.h>
#include<stdlib.h>
#define eleType int
// 定义节点
typedef struct Node
{
eleType data;
struct Node* next;
}Node;
// 定义栈
typedef struct
{
Node* head;
size_t size;
}Stack;
// 初始化
void StackCreat(Stack* stk){
stk->head = NULL;
stk->size = 0;
}
// 摧毁栈
void StackDestroy(Stack* stk){
while(stk->head){
Node* next = stk->head->next;
free(stk->head);
stk->head = next;
}
stk->size = 0;
}
// 压入元素 头插法
void StackPush(Stack* stk,eleType element){
Node* newnode = (Node*)malloc(sizeof(Node)); // 先创建一个节点 赋值
newnode->data = element;
newnode->next = stk->head; // 更新栈头
stk->head = newnode; // 更新头节点
stk->size++;
}
// 弹出元素
eleType StackPop(Stack* stk){
if(stk->size == 0){
printf("空栈\n");
exit(1);
}
eleType result = stk->head->data; // 弹出后释放内存
Node* next = stk->head->next; // 记录头节点的后继以便更新头节点
free(stk->head);
stk->head = next; // 更新头节点
stk->size--; // 大小减一
return result; // 返回弹出元素的值
}
eleType StackTop(Stack* stk){
if(stk->size == 0){
printf("空栈\n");
exit(1);
}
return stk->head->data;
}
int Stacksize(Stack* stk){
return stk->size;
}
int main(){
Stack stk;
StackCreat(&stk);
StackPush(&stk, 10);
StackPush(&stk, 20);
StackPush(&stk, 30);
printf("top is %d\n",StackTop(&stk));
printf("pop is %d\n",StackPop(&stk));
printf("size is %d\n",Stacksize(&stk));
StackDestroy(&stk);
return 0;
}