数据结构 栈和队列

发布于:2025-02-15 ⋅ 阅读:(118) ⋅ 点赞:(0)

一、栈

        栈是⼀种只允许在⼀端进⾏数据插⼊和删除操作的线性表。
        • 进⾏数据插⼊或删除的⼀端称为栈顶,另⼀端称为栈底。不含元素的栈称为空栈。
        • 进栈就是往栈中放⼊元素,出栈就是将元素弹出栈顶。

如果定义了⼀个栈结构,那么添加和删除元素只能在栈顶进⾏。不能随意位置添加和删除元素,这是栈这个数据结构的特性,也是规定。

栈的模拟实现:

创建:
1. 本质还是线性表,因此可以创建⼀个⾜够⼤的数组,充当栈结构
2. 再定义⼀个变量n ,⽤来记录栈中元素的个数,同时还可以标记栈顶的位置。

const int N = 1e6 + 10;
int n;
int stk[N];

进栈:
这⾥依旧舍弃下标为0 的位置,有效元素从1 开始记录。
进栈操作,那就把元素放在栈顶位置即可。

// 进栈 
void push(int x)
{
 stk[++n] = x;
}

出栈

不⽤真的删除元素,只⽤将元素个数减1 ,就相当于删除栈顶元素。

// 出栈 
void pop()
{
 n--;
}

栈顶元素:
查询栈顶元素。
这⾥要注意,因为栈特殊的规定,不⽀持遍历整个栈中的元素。因此,需要查找栈中元素的时候,只能查找到栈顶元素。

// 栈顶元素 
int top()
{
 return stk[n];
}

判空:
判断栈是否为空

// 判空 
bool empty()
{
 return n == 0;
}

有效元素的个数

// 栈中元素个数 
int size()
{
 return n;
}

二、stack

创建
stack<T> st; 
T 可以是任意类型的数据。

size/empty
1. size :返回栈⾥实际元素的个数;
2. empty :返回栈是否为空。
时间复杂度:O(1) 。

push/pop
1. push :进栈;
2. pop :出栈。
时间复杂度:O(1) 。

top
1. top :返回栈顶元素,但是不会删除栈顶元素。
时间复杂度:O(1) 。

#include <iostream>
#include <stack>
using namespace std;
int main()
{
 stack<int> st;
 // 先讲 1~10 进栈 
 for(int i = 1; i <= 10; i++)
 {
 st.push(i);
 }
 while(st.size()) // !st.empty()
 {
 cout << st.top() << endl;
 st.pop();
 }
 return 0;
}

三、队列

队列也是⼀种访问受限的线性表,它只允许在表的⼀端进⾏插⼊操作,在另⼀端进⾏删除操作。
• 允许插⼊的⼀端称为队尾,允许删除的⼀端称为队头。
• 先进⼊队列的元素会先出队,故队列具有先进先出(FirstInFirstOut)的特性。

创建
• ⼀个⾜够⼤的数组充当队列;
• ⼀个变量h 标记队头元素的前⼀个位置;
• ⼀个变量t 标记队尾元素的位置。

const int N = 1e6 + 10;
int h, t; // 队头指针,队尾指针 
int q[N]; // 队列

⼊队
• 将x这个元素放⼊到队列中。
注意,我们这⾥依旧从下标为1的位置开始存储有效元素。

// ⼊队 
void push(int x)
{
 q[++t] = x;
}

出队
• 删除队头元素。

// 出队 
void pop()
{ 
 h++;
}

队头
• 返回队列⾥⾯的第⼀个元素。
队尾
• 返回队列⾥⾯的最后⼀个元素

判空
• 判断队列是否为空。

// 队列是否为空 
bool empty()
{
 return t == h;
}

元素个数
• 返回队列⾥⾯元素的个数。

四、queue

创建
queue<T> q;
T 可以是任意类型的数据。

size/empty
size :返回队列⾥实际元素的个数;

empty :返回队列是否为空。

push/pop
1. push :⼊队;
2. pop :出队。
时间复杂度:O(1) 。

front/back
1. front :返回队头元素,但不会删除;
2. back :返回队尾元素,但不会删除。
时间复杂度:O(1) 。

#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
int main()
{
 // 测试 queue 
 queue<PII> q;
 for(int i = 1; i <= 10; i++)
 {
 q.push({i, i * 10});
 }
 while(q.size()) // while(!q.empty())
 {
 auto t = q.front();
 q.pop();
 cout << t.first << " " << t.second << endl;
 }
 return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到