zoukankan      html  css  js  c++  java
  • 栈和队列

    一、栈

    1.栈的定义

         栈是一种线性表,一种抽象数据类型,它只允许在一端进行插入或删除操作。又叫做LIFO(后进先出)线性表。

         栈的基本操作有入栈push和出栈pop,栈顶top指的是进行操作的一端。如图,只有栈顶元素可以访问。进栈次序为a1、a2、a3、a4、a5,出栈次序为a5、a4、a3、a2、a1

     

    2.栈的实现

         栈是受限的线性表,因此任何实现表的方法都能实现栈,主要就是顺序栈和链栈。

    2.1 顺序栈

         使用数组存放栈的数据元素,设有一个头指针top执行栈顶,初始时为top=0,顺序栈的实现代码:

    进栈:先放在top+1

    public void push(T item){
        if(top >= capacity) return;
        items[top] = item;
        top ++;
    }

    出栈:先top-1再取

    public T pop(){
        if(top < 0) return null;
        return (T) items[--top];
    }

    2.2 链栈

         通常采用单链表实现,所有的操作都在表头进行。栈节点为:

    private class Node{
        T item;
        Node next;
    }

         链栈的实现代码,有一个头指针top,只能用top指针执行push、pop(插入删除)

    进栈:头插法

    public void push(T item){
        Node old = top;
        top = new Node();
        top.item = item;
        top.next = old;
        count++;
    }

    出栈:取时只需把top节点指向下个节点即可

    public T pop(){
        T item = top.item;
        top = top.next;
        count--;
        return item;
    }

    二、队列

    1.队列

         只在一端插入,另一端删除的线性表,类似于日常的排队,特性是先进先出FIFO。其中有两个指针,头指针head和尾指针tail,在tail插入,在head读取。

     

    2.队列的实现

    2.1 顺序存储

          使用数组,初始状态时,head=tail=0;当tail==MaxSize时,并不能说明队列满了,当head指针为tail的前一个位置,此时队列中只有一个元素,但没满,这时入队出现上溢出,这时一种假溢出。

    2.1.1 循环队列

          也称环形队列,环形缓冲区,臆造一个环状的空间,当队头或队首指针达到最大时,重置为零,可以使用取余运算实现,(也能不用取余)。

    取余运算:

    初始时,head = tail = 0;
    队首加1,head = (head + 1) % MaxSize;
    队尾加1,tail = (tail + 1) % MaxSize;
    队列长度,(tail + MaxSize - head) % MaxSize;

    不使用取余:

         以RingBuffer环形缓冲区为例,具体代码在GitHub,其中入队和出队的代码如下,没使用取模运算,(对计算机来说,加1减1比取模简单)

    入队:

    public boolean put(T item){
        int next = tail + 1;
        if(next >= bufferSize){
            next = 0;
        }
        if(next == head){
            lost++;
            return false;
        }
        rBuffer[next] = item;
        tail = next;
        return true;
    } 

    出队:

    public T get(){
        if(head == tail){
            return null;
        }
        @SuppressWarnings("unchecked")
        T item = (T) rBuffer[head];
        rBuffer[head] = null;
        
        if(++head >= bufferSize){
            head = 0;
        }
        return item;
    }

    2.2 链式存储

    链队列,使用一个带有队头head和队尾tail指针的单链表,在head读取,在tail插入。节点类型如下:

    private Node head; // 队头
    private Node tail; // 队尾
    private class Node{ // 节点
        T item;
        Node next;
    }

    入队:

    public void enqueue(T item){
        Node old = tail;
        tail = new Node();
        tail.item = item;
        tail.next = null;
        if(isEmpty()){
            head = tail;
        } else {
            old.next = tail;
        }
        count++;
    }

    出队:

    public T dequeue(){
        T res = head.item;
        head = head.next;
        if(isEmpty()){
            tail = null;
        }
        count--;
        return res;
    }

    源码地址:https://github.com/cyhe/algorithm/tree/master/src/algo/linearlist/stack

     

    作 者:创心coder
    QQ群:361982568
    订阅号:cxcoder
    文章不足之处,还请谅解!本文会不断完善更新,转载请保留出处。如果帮到了您,烦请点赞,以资鼓励。
  • 相关阅读:
    网络技术
    AWS责任共担模型
    AWS 创建新用户(IAM用户)
    AWS系列-申请Redis
    AWS系列-申请MySQL
    MDX之Case When用法
    SSAS中雪花模型
    SSAS中处理时经常出现的几种错误
    C#连接Oracle中文乱码问题解决方法
    BI中PowerDesigner建模
  • 原文地址:https://www.cnblogs.com/cwane/p/5491982.html
Copyright © 2011-2022 走看看