栈和队列

一、栈

1.栈的定义

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

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

 栈和队列_第1张图片

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.队列的实现

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

 

你可能感兴趣的:(栈和队列)