栈
一、栈的定义
栈(Stack) 是一种只允许在表头(或顶端)存取数据的表,栈顶是允许操作的,而栈底是固定的。即只能在栈的顶端放入数据元素,并且只能从栈的顶端移出数据元素。正是基于这种原因,栈也被称为“后进先出”结构。
二.栈的一些基本操作
1.入栈
1.定义一个栈结构体
const int MAX_SIZE = 100;
typedef struct
{
int data[MAX_SIZE]; //存入的数据
int top; //定义栈顶为top
}stack;
2.初始化栈
void initstack(stack* s)
{
s->top = -1;
//如果栈内没有元素那么top指向-1,如果有元素入栈直接top++即可
}
3.判断栈是否为空
int isempty(stack* s)
{
if (s->top == -1)
{
printf("栈是空的\n");
return 1;
}
return 0;
}
4.入栈
void push(stack* s, int e) //e是想要存入的元素
{
if (s->top >= MAX_SIZE)
{
//第一个元素的索引是0所以最大索引为MAX_SIZE-1
printf("栈已经满了,不能进行压栈\n");
return;
//如果栈顶的索引超过了最大的索引,则说明栈已经满了不能再进行压栈
}
else
{
s->top++; //栈顶索引加一,并且将数据存入元素的数组之中
s->data[s->top] = e;
return;
}
}
2.出栈
void pop(stack* s, int* e)
{
if (s->top == -1) //如果索引为-1,则说明栈为空了
{
printf("栈已经空了,不能再进行出栈");
return;
}
else
*e = s->data[s->top]; //用一个指针e存出栈的数据元素
s->top--; //栈顶减1表示出栈
return;
}
3.获取栈顶元素
int get_top(stack* s, int* e)
{
if (s->top == -1)//栈为空
{
printf("栈为空,无法获取栈顶的元素\n");
return 0;
}
*e = s->data[s->top];//用e来存栈顶的元素
return 1;
}
4.完整代码
#include<iostream>
using namespace std;
const int MAX_SIZE = 100;
//定义栈结构体
typedef struct
{
int data[MAX_SIZE];
int top;
}stack;
//初始化
void initstack(stack* s)
{
s->top = -1;
}
//判断是否为空
int isempty(stack* s)
{
if (s->top == -1)
{
printf("栈是空的\n");
return 1;
}
return 0;
}
//入栈
void push(stack* s, int e) //e是想要存入的元素
{
if (s->top >= MAX_SIZE)
{
//第一个元素的索引是0所以最大索引为MAX_SIZE-1
printf("栈已经满了,不能进行压栈\n");
return;
//如果栈顶的索引超过了最大的索引,则说明栈已经满了不能再进行压栈
}
else
{
s->top++; //栈顶索引加一,并且将数据存入元素的数组之中
s->data[s->top] = e;
return;
}
}
//出栈
void pop(stack* s, int* e)
{
if (s->top == -1) //如果索引为-1,则说明栈为空了
{
printf("栈已经空了,不能再进行出栈");
return;
}
else
*e = s->data[s->top]; //用一个指针存入退出栈的数据元素
s->top--;
//栈顶减1表示出栈
return;
}
//获取栈顶元素
int get_top(stack* s, int* e)
{
if (s->top == -1)//栈为空
{
printf("栈为空,无法获取栈顶的元素\n");
return 0;
}
*e = s->data[s->top];
return 1;
}
int main()
{
stack s;
initstack(&s);//初始化
isempty(&s);//判断为空
int e,num;
//1.入栈
cout << "请输入要入栈的元素个数" << endl;
cin >> num;
cout << "请输入要入栈的元素:" << endl;
for (int i = 0; i < num; i++)
{
cin >> e;
push(&s, e);
}
//2.出栈
cout << "请输入出栈元素的个数:" << endl;
int m;
cin >> m;
printf("出栈的元素为\n");
for (int i = 0; i < m; i++)
{
pop(&s, &e);
cout << e << " ";
}
//3.获取栈顶元素
get_top(&s, &e);
printf("栈顶元素是%d", e);
return 0;
}
三.动态分配内存
1.定义栈结构体
const int MAX_SIZE = 100;
typedef struct
{
int *data;
int top;
}stack;
2. malloc
-
malloc
函数的主要作用是动态地分配内存空间。程序可以更加灵活地管理内存,适应不同大小的数据结构和变化的数据。注:必须使用
free
来释放它,以避免内存泄漏 -
头文件
#include <stdlib.h> //c语言
#include <cstdlib> //c++
-
内存分配失败
如果
malloc
堆内存中无法找到足够大的空闲块满足请求,或者由于其他原因(如内存耗尽)无法分配内存,返回NULL
指针。 -
内存分配成功的返回值
如果内存分配成功,
malloc
返回一个指向所分配内存的指针,该指针的类型是void *
。 -
分配内存空间
#include <iostream> #include <cstdlib> int main() { size_t num = 10; //分配一个包含10个整数的数组 size_t size = num * sizeof(int); // 计算总字节数 int *arr = (int *)malloc(size); //分配内存 free(arr); //释放内存 return 0; }
-
检查是否成功分配内存
int *arr = (int *)malloc(size); if (arr == NULL) { // 内存分配失败 printf("内存分配失败"); return 1; }
3.动态分配
stack* initstack()
{
stack* s = (stack*)malloc(sizeof(stack));
//malloc的返回值是指针类型所以用*s来接收
s->data = (int*)malloc(sizeof(int) * MAX_SIZE);
//给data开辟内存
s->top = -1;
//栈顶指针指向-1,即没有元素
return s;
}
4.判断栈是否为空
int isEmpty(stack* s) {
if (s->top == -1) //如果栈顶为-1,说明栈为空
{
printf("空");
return true;
}
else
{
printf("不空");
return false;
}
}
5.获取栈顶元素
int getTop(stack s, int& e) { //把栈顶存储到e中
if (s.top==-1) { //如果栈为空
printf("栈为空,无法获取栈顶的元素\n");
return 0;
}
e = s.top - 1;//用e来存栈顶的数据
return 1;
}
四.栈的链式结构
1.定义一个链表
const int MAX_SIZE = 100;
typedef struct
{
int data;
stack*next;
}stack;
2.初始化
stack*initstack()
{
stack* s = (stack*)malloc(sizeof(stack));
s->data = 0;
s->next = NULL;
return s;
}
3.判断是否为空
int isEmpty(stack* s)
{
if (s->next == NULL)//判断栈的下一个节点是否为空
{
printf("空的");
return 1;
}
else return 0;
}
4.入栈
int push(stack* s, int e)
{
stack* p = (stack*)malloc(sizeof(stack));
p->data = e;
p->next = s->next;
s->next = p;
return 0;
}
5.出栈
int pop(stack* s, int* e)
{
if (s->next == NULL)
{
printf("空的");
return 0;
}
*e = s->next->data; //获取栈顶元素
stack* q = s->next;
s->next = q->next;
free(q); //释放内存
return 1;
}
五.STL-stack
容器
1.构造
stack
对象的默认构造形式: stack 名称; T:数据类型
如:stack s; //一个存放int的stack容器。
2.入栈
s.push()
void test()
{
stack<int>s;//构造容器
s.push(10);//往栈头添加元素6
}
3.判断元素是否为空
s.empty()
while (!s.empty())
{
cout << "栈不为空" << endl;
break;
}
4.栈的大小
s.size()
cout << "栈的大小" << s.size() << endl;
5.最后一个入栈的元素
s.top()
cout << "最后一个入栈的元素" << s.top() << endl;
6.出栈
s.pop()
7.赋值
stack&operator=(const stack &s)
stack<int>sA;
sA.push(1);
sA.push(2);
stack<int>sB;
sB=sA;
8.交换
s.swap()
stack<int>sA;
sA.push(1);
sA.push(2);
stack<int>sB;
sB = sA;
sA.swap(sB); //交换
cout << sA.size() << endl;
cout << sB.size() << endl;
7.完整代码
#include<iostream>
#include<stack>
using namespace std;
void test()
{
stack<int>s;
s.push(10);//往栈头添加元素6
s.push(20);
s.push(30);
s.push(40);
s.push(50);
//判断是否为空
while (!s.empty())
{
cout << "栈不为空" << endl;
break;
}
//栈的大小
cout << "栈的大小" << s.size() << endl;
//返回最后一个压入栈的元素
cout << "最后一个入栈的元素" << s.top() << endl;
//出栈
s.pop();
s.pop();
//赋值
stack<int>sA;
sA.push(1);
sA.push(2);
stack<int>sB;
sB = sA;
//交换
sA.swap(sB);
cout << sA.size() << endl;
cout << sB.size() << endl;
}
int main()
{
test();
return 0;
}