数据结构:栈和队列

1、什么是栈

( S t a c k ) (Stack) (Stack)又称为堆栈,是一种受限制的线性表只允许从一端插入和删除数据。因为栈的插入和删除只能在栈顶进行,所以每次删除的元素都是栈中的最后一个元素,故栈的特征是先进后出 ( L I F O ) (LIFO) (LIFO)

2、栈的相关概念

  1. 栈顶与栈底:允许元素插入与删除的一端称之为栈顶,另一端称之为栈底。
  2. 压栈:栈的插入操作称之为进栈,也称之为压栈,入栈。
  3. 弹栈:栈的删除操作称之为出栈。
  4. 空栈:不含有任何元素的空表。

3、栈的基本操作

  1. 弹栈:通常名为 p o p pop pop
  2. 压栈:通常名为 p u s h push push
  3. 求栈的大小。
  4. 判断栈是否为空。
  5. 获取栈顶元素的值。

4、栈的常见分类

1、顺序栈

采用顺序存储的栈称之为顺序栈。利用一组地址连续的存储单元存放从栈底到栈顶的元素,同时用一个指针指向当前栈顶元素的位置(也可以指向当前栈顶元素的前一个位置),以下都以指向栈顶元素为准。

顺序栈几乎是基于数组的栈——以数组为底层数据结构,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向。

#include <iostream>
using namespace std;
#define endl '\n'
int st[100];//用数组存储
int top = -1;//指针始终指向栈顶
int main(){
    for(int i = 1; i <= 10; i++){
        st[top++] = i;//入栈
    }
    cout << "the size of the stack is " << top + 1 << endl;//栈的大小
    while(top != -1){//判断栈是否为空
        cout << st[--top] << " ";//出栈
    }
    return 0;
}

2、共享栈

利用栈底位置相对不变的特性,可让两个顺序栈共享一个数组空间,将两个栈的栈底分别置于数组的两端,两个栈顶向共享空间的中间生长。

数据结构:栈和队列1

两个栈的指针都指向当前栈顶元素, t o p 0 = − 1 top_0=-1 top0=1为左侧栈为空, t o p 1 = M a x S i z e top_1=MaxSize top1=MaxSize为右侧栈为空;当且仅当两个栈顶指针相邻 ( t o p 0 + 1 = t o p 1 ) (top_0+1=top_1) (top0+1=top1)时,判断为栈满。

3、链栈

采用链式存储的栈称之为链栈,以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部。优点:不存在栈满溢出的情况。

#include <iostream>
using namespace std;
template<class T>class stack{
    private:
        struct Node{
            T data;
            Node *next;
        };
        Node *head;
        Node * p;
        int length;
    public:
        stack(){
            head = NULL;
            length = 0;
        }
        void push(T n){
            Node * q = new Node;
            q->data = n;
            if(head == NULL){
                q->next = head;
                head = q;
                p = q;
            }
            else{
                q->next = p;
                p = q;
            }
            length++;
        }
        T pop(){
            if(length <= 0){
                abort(); // 中止程序执行,直接从调用的地方跳出
             }
             Node *q;
             T data;
             q = p;
             data = p->data;
             p = p->next;
             delete q;
             length--;
             return data;
         }
         int size(){
            return length;
         }
         T top(){
            return p->data;
         }
         bool empty(){
            if(length == 0) return true;
            else return false;
         }
         void clear(){
            if(length > 0) pop();
         }
};
int main(){
    stack<int>st;  //定义一个整型栈
    for(int i = 1; i <= 10; i++){
        st.push(i); // 将元素压栈
    }
    cout << "the size of the stack is " << st.size() << endl; //判断栈的大小
    while(!st.empty()){ //判断栈是否为空
        cout << st.top() << " "; //返回栈顶元素的数值
        st.pop(); // 弹出栈顶元素
    }
    system("pause");
    return 0;

}
//the size of the stack is 10
//10 9 8 7 6 5 4 3 2 1

5、什么是队列

队列 ( q u e u e ) (queue) (queue)是只允许在一端进行插入操作,另一端进行删除操作的线性表。它是一种先进先出的线性表,简称 F I F O FIFO FIFO,允许插入的一端称为队尾,允许删除的一端称为队头。不包含任何元素的队列称之为空队列

6、常见的基本操作

  1. 出队:通常名为 p o p pop pop
  2. 入队:通常名为 p u s h push push
  3. 求队列的大小。
  4. 判断队列是否为空。
  5. 获取栈顶元素的值。
  6. 获取队列第一个元素。
  7. 获取队列最后一个元素。

数组模拟队列

使用数组模拟队列,也称之为顺序队列,指用一块连续的存储单元存放队列中的元素,并用两个指针分别指向队列的收尾。

int q[Size], rear = front = 0;
  • 插入元素: q [ + + r e a r ] = x q[++rear] = x q[++rear]=x
  • 删除元素: f r o n t + + front++ front++
  • 访问队首: q [ f r o n t ] q[front] q[front]
  • 访问队尾: q [ r e a r ] q[rear] q[rear]
  • 清空队列: r e a r = f r o n t = 0 rear = front = 0 rear=front=0

看完代码我们发现,当我们一直重复入队出队的操作时,我们终将会“用完”数组的所用空间,但是事实上,出队的元素的空间已经被空留出来的,这就出现了假溢出。

循环队列

解决假溢出的方法就是,我们将队列首尾相互连接形成一个循环,我们将这个循环称之为循环队列。

当队首指针 f r o n t = M a x S i z e − 1 front=MaxSize-1 front=MaxSize1后,再前进一位就自动回到 0 0 0,这可以采用取模运算来实现。

  1. 初始化: f r o n t = r e a r = 0 front=rear=0 front=rear=0
  2. 队首指针进 1 1 1位: f r o n t = ( f r o n t + 1 ) % M a x S i z e front=(front+1)\%MaxSize front=(front+1)%MaxSize
  3. 队尾指针进 1 1 1位: r e a r = ( r e a r + 1 ) % M a x S i z e rear=(rear+1)\%MaxSize rear=(rear+1)%MaxSize
  4. 队列长度: ( r e a r − f r o n t + M a x S i z e ) % M a x S i z e (rear-front+MaxSize)\%MaxSize (rearfront+MaxSize)%MaxSize
  5. 队满条件: ( r e a r + 1 ) % M a x S i z e = = f r o n t (rear+1)\%MaxSize==front (rear+1)%MaxSize==front
  6. 队空条件: f r o n t = r e a r front=rear front=rear
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星*湖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值