一. 链式栈
之前已经用数组实现了栈,用链栈也遵循先进后出的特点即可。
用链表实现入栈和出栈可以考虑头插法入栈和尾插法入栈。但不采用尾插法,因为这样每入栈或出栈一次,都要对栈进行一次遍历,增加了程序的复杂性。因此采用头插法,得到的链栈栈底元素为链表末尾元素,栈顶元素是头结点后的元素。
class LinkStack{ Entry head;//头结点 class Entry{ int data; Entry next; public Entry(){ this.data = -1; this.next = null; } public Entry(int val){ this.data = val; this.next = null; } } public LinkStack(){//类的构造函数 this.head = new Entry(); } }
1. 入栈
public void push(int val){ Entry entry = new Entry(val); entry.next = this.head.next; this.head.next = entry; }
2. 出栈
public boolean pop(){ if(head.next != null){//判断栈是否为空 this.head.next = this.head.next.next; return true; } return false; }
3. 得到栈顶元素
public int getTop(){ if(this.head.next != null){ return head.next.data; } return -1; }
4.打印栈内元素
public void show(){ Entry cur = head.next; while(cur != null){//遍历链表打印 System.out.print(cur.data+" "); cur = cur.next; } System.out.println(); }
测试一下
二. 循环队列
队列是一种先进先出的线性数据结构,即在队头进行删除,在队尾进行插入。队头用front表示,队尾用rear表示。
实现顺序队考虑用数组,但由于数组的长度有限,可能会出现如图假溢出的情况
循环队列
因此,我们构造的循环队列应该如下图
接下来看一下关于队列的基本操作
class QueueLink{ int[] elem;//存放队列元素的数组 int front;//队头 int rear;//队尾 int usedSize = 0;//循环队列内部的有效数据个数,即队列的长度 int allSize = 10;//数组长度 public QueueLink(){ this(10); } public QueueLink(int size){ this.elem = new int[size]; this.front = 0; this.rear = 0; } }
1. 判断队空
front = rear,队列为空
public boolean isEmpty(){ return front == rear;//相等为true不相等为false }
2.判断队满
front = (rear + 1)%allsize
public boolean isFull(){ if(this.front == (this.rear + 1) % allSize){//有一个闲置单元 return true; } return false; }
3.入队
public void push(int val){ if(isFull()){//队满不能入队 return; } this.elem[this.rear] = val; this.rear = (this.rear + 1) % allSize;//不能rear++,rear一直在0~allsize-1的范围内 this.usedSize++;//队列长度加一 }
4. 出队
public void pop(){ if(isEmpty()){//队空不出队 return; } this.elem[front] = -1;//给出队的位置标志-1,表示这个元素已出队 this.front = (this.front + 1)%allSize;//front后移一位 this.usedSize--;//队列长度减一 }
5.得到队头
public int getTop(){ if(isEmpty()){//判断队空 return -1; } return this.elem[front];//把front位置的元素return出去 }
三. 用两个栈实现一个队列
public class TestDemo8 { Stack s1 = new Stack(); Stack s2 = new Stack(); public void pushQue(int val){//入队 if(s1.isFull()){ return; } s1.push(val); } public void popQue(){ if(s1.isEmpty()){ return; } while(s1.top > 1){//将s2除栈顶以外的元素放入s2 s2.push(s1.getpop()); s1.top--; } s1.top = 0; while(s2.top>0){//将s2的元素放回s1 s1.push(s2.getpop()); s2.top--; } } public int getFront(){//得到队头 if(s1.isEmpty()){ return -1; } return s1.elem[0]; } public void show(){ for(int i = 0;i < s1.top;i++){ System.out.print(s1.elem[i]+" "); } System.out.println(); } public static void main(String[] args) { TestDemo8 t= new TestDemo8(); t.pushQue(5); t.pushQue(6); t.pushQue(7); t.show(); t.popQue(); t.show(); } }