C++用栈实现先入先出队列相关知识与代码实现

1、栈(stack)的基本知识

C++的栈是一种数据结构,它是一个后进先出(LIFO)的线性结构,具有两个基本操作:push和pop。

push操作将数据压入栈顶,而pop操作将栈顶数据弹出。
C++中的栈实现在STL中,可以使用std::stack来创建一个栈。
std::stack可以被视为一种容器适配器,它基于其他容器实现,
例如std::deque和std::list。

适用场景:
在C++中,栈通常用于实现函数调用堆栈和表达式求值等场景。当一个函数被调用时,它的返回地址和其他必要数据被压入栈中,当函数返回时,这些数据被弹出

 

             

基本存储方式:

(1)顺序存储:利用一段连续的内存空间进行存储。

(2)链式存储:利用非连续的内存空间存储,元素之间使用指针进行链接。(通常单链表实现,栈顶是表头,栈底的表尾)。

构造函数:

  构造函数原型 解释
1 stack<T> stk 默认构造
2 stack(const stack &stk) 拷贝构造

赋值操作:

  函数原型:= 解释
1 stack& operator=(const stack &stk) 重载=操作符

数据存取:

  函数原型:push、pop、top 解释
1 push(elem) 入栈:向栈顶添加元素
2 emplace() 入栈:构造和添加元素
3 pop() 出栈:移除当前栈顶元素
4 top() 返回栈顶元素

push与emplace的异同点:

  • 对于int、double等内置数据类型而言,push()emplace()是相同的
  • 对于自定义数据类型而言,使用push()前必须先将要添加的对象构造出来(实例化),而使用emplace()既可以填入实例化的对象也可以填入对象的构造参数

2、栈(stack)的相关术语和基本操作

栈顶(top):

线性表允许插入和删除的那一段。值得注意的是,栈顶指针top的指向是有些两种方式的,一种是指向栈顶当前元素,一种是指向栈顶的下一位置。

栈底(bottom):

固定的,不允许进行插入和删除的另一端。

空栈:

不含有任何元素的空表。

基本操作:

(1)栈判空:

1 bool isEmpty(SqStack S)
2 {
3     if (S.top==-1)
4     {
5         return true;
6     }
7     return false;
8 }

(2)栈判满

1 bool isFull(SqStack S)
2 {
3     if (S.top == MAXSIZE - 1)
4     {
5         return true;
6     }
7     return false;
8 }

(3)入栈

 1 bool Push(SqStack& S, ElemType e)
 2 {
 3     bool flag = isFull(S);
 4     if (flag==true)
 5     {
 6         printf("栈满\n");
 7         return false;
 8     }
 9     S.top++;
10     S.data[S.top] = e;
11     return true;
12  
13 }

(4)出栈

 1 bool Pop(SqStack& S, ElemType& e)
 2 {
 3     bool flag = isEmpty(S);
 4     if (flag)
 5     {
 6         printf("栈空\n");
 7         return false;
 8     }
 9     e = S.data[S.top];
10     S.top--;
11     return true;
12 }

(5)取栈顶

 1 //取栈顶
 2 bool GetTop(SqStack& S, ElemType& e)
 3 {
 4     bool flag = isEmpty(S);
 5     if (flag)
 6     {
 7         return false;
 8     }
 9     e = S.data[S.top];
10     return true;
11 }

(6)初始化一个空栈

InitStack(&s);

(7)判断一个在栈是否为空

StackEmpty(s);

3、栈的代码测试

 1 int _tmain(int argc, _TCHAR* argv[])
 2 {
 3     ArrayStack <int> p(5);
 4     for (int i = 0; i < 5; i++)
 5     {
 6         p.push(i);
 7     }
 8     cout << "栈的大小:"<<p.size() << endl;
 9     cout << "栈是否为空:"<<p.isEmpty() << endl;
10     cout << "栈顶元素:"<<p.top() << endl;
11     cout << "依次出栈:" << endl;
12     while (!p.isEmpty())
13     {
14         cout << p.pop() << endl;
15     }
16     getchar();
17     return 0;
18 }

 4、队列的基本知识

  •  与栈相比,栈是先进后出,队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构。
  •  在队尾添加元素,在队头删除元素。

队列(queue)的结构如下:类似于生活中的排队买票,最先排队的人位于队伍最前端,后来的人依次从队伍末尾加入队伍。当队首的人买票成功后离开,原先位于第二位的人顶上成为新的队首,后续以此类推。

           

相关术语 :

(1)入队:队列的插入操作。   允许插入数据的位置叫队尾 

(2)出队:队列的删除操作。   允许删除数据的位置叫队头

 操作:

  1.  入队: 通常命名为push()
  2.  出队: 通常命名为pop()

 queue构造函数:

  构造函数原型 解释
1 queue<T> que 默认构造
2 queue(const queue &que) 拷贝构造

 queue赋值操作:

  函数原型:= 解释
1 queue& operator =(const queue &que) 重载 = 操作符

 queue数据存取:

  函数原型:push、pop、back、front 解释
1 push(elem) 向队尾添加队尾
2 emplace() 向队尾添加元素
3 pop() 移除当前队首元素
4 back() 返回队尾元素
5 front() 返回队首元素

queue其他操作:

  函数原型:empty、size、swap 解释
1 empty() 判断队列是否为空
2 size() 返回队列的大小
3 swap(queue<T> & que) 将当前队列中元素和que中元素交换

5、整体所需操作

队列

1 queue<int> q; //定义一个空队列q
2 
3 push(x) -- 将一个元素放入队列的尾部。
4 pop() -- 从队列首部移除元素。
5 peek() -- 返回队列首部的元素。//同front()
6 empty() -- 返回队列是否为空。
7 back()访问队尾元素
8 size()访问队中的元素个数

1 stack<int> s;
2 
3 push(x) -- 元素 x 入栈
4 pop() -- 移除栈顶元素
5 top() -- 获取栈顶元素
6 empty() -- 返回栈是否为空

6、用栈实现队列代码解释

官方:

将一个栈当作输入栈,用于压入 push传入的数据;另一个栈当作输出栈,用于 pop和 peek操作。

每次 pop或 peek时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。

 1 class MyQueue {
 2 private:
 3     stack<int>inStack, outStack;
 4 
 5     void in2out(){
 6         while (!inStack.empty()) {
 7             outStack.push(inStack.top());
 8             inStack.pop();
 9         }
10     }
11 
12 public:
13     MyQueue() {
14 
15     }
16     
17     void push(int x) {
18         inStack.push(x);
19     }
20     
21     int pop() {
22         if (outStack.empty()){
23             in2out();
24         }
25 
26         int x = outStack.top();
27         outStack.pop();
28         return x;
29 
30     }
31     
32     int peek() {
33         if (outStack.empty()){
34             in2out();
35         }
36         return outStack.top();
37 
38     }
39     
40     bool empty() {
41         return inStack.empty() && outStack.empty();
42 
43     }
44 };
45 
46 /**
47  * Your MyQueue object will be instantiated and called as such:
48  * MyQueue* obj = new MyQueue();
49  * obj->push(x);
50  * int param_2 = obj->pop();
51  * int param_3 = obj->peek();
52  * bool param_4 = obj->empty();
53  */

 

 

 

posted @ 2024-03-05 00:15  taohuaxiaochunfeng  阅读(282)  评论(0编辑  收藏  举报