一. 链式栈
之前已经用数组实现了栈,用链栈也遵循先进后出的特点即可。
用链表实现入栈和出栈可以考虑头插法入栈和尾插法入栈。但不采用尾插法,因为这样每入栈或出栈一次,都要对栈进行一次遍历,增加了程序的复杂性。因此采用头插法,得到的链栈栈底元素为链表末尾元素,栈顶元素是头结点后的元素。
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();
}
}