链式栈与循环队列

链式栈是一种数据存储结构,可以通过单链表的方式来实现,使用链式栈的优点在于它能够克服用数组实现的顺序栈空间利用率不高的特点,但是需要为每个栈元素分配额外的指针空间用来存放指针域。
链式栈的定义及其基本操作:

package practice;
/*入栈使用头结点
 * 出栈只用删除head.next
 * 
 * */
class LinkStack1{
    class Entry{        //链式栈的定义
        int data;       //数据域
        Entry next;     //指针域
        public Entry(){           //无参构造方法
            this.data = -1;
            this.next = null;
        }
        public Entry(int data){   //有参构造方法
        this.data = data;
        this.next = null;
        }
    }
    private Entry head = null;   //头结点的定义
    public LinkStack1(){         //头结点的初始化
        this.head = new Entry();
    }

    //入栈--->头插法
    public void insertHead(int val){
        Entry entry = new Entry(val);
        entry.next = this.head.next;
        this.head.next = entry;
    }

    //出栈--->出头结点的下一个
    public void pop(){
        Entry cur = this.head.next;
        if(cur == null){
            return;
        }
        this.head.next = cur.next;
        cur = null; //出栈元素制空
        return;
    }

    //得到栈顶元素
    public int getTop(){
        Entry cur = this.head.next;
        if(cur == null){
            return -1;
        }
        return cur.data;
    }
    //show
    public void show(){
        Entry cur = this.head.next;
        while(cur != null){
            System.out.print(cur.data+" ");
            cur = cur.next;
        }
        System.out.println();
    }

}
public class LinkStack {

    public static void main(String[] args) {
        LinkStack1 t1 = new LinkStack1();//初始化一个链式栈对象
        for(int i=0;i<5;i++){//循环入栈
            t1.insertHead(i);
        }
        System.out.print("入栈后栈内元素:");
        t1.show();
        System.out.print("出栈后栈内元素:");
        t1.pop();
        t1.show();
        System.out.println("栈顶元素为:"+t1.getTop());
    }

}

运行结果:
这里写图片描述
循环队列为充分利用向量空间,克服”假溢出”现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列。
这里写图片描述
循环队列的定义及其基本操作:

package practice;
/*
 * 循环队列
 * 先进先出
 * 循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,
 * 造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。
 * 浪费一个数据单元 来判断是否为满
 * 
 * */

class QueueLink{
    int elem[];
    int front;//队头
    int rear;//队尾
    int useSize=0;//队列中有效数据个数
    int allSize=8;//队列的最大长度

    public QueueLink(){//无参构造方法
        this(10);
    }
    public QueueLink(int size){//有参构造方法
        this.elem = new int[size];
        this.front = 0;
        this.rear = 0;
    }

    //判断是否为满
    public boolean isFull() {
        if((this.rear+1)%this.allSize == this.front){
            //由于rear,front均为所用空间的指针,循环只是逻辑上的循环,所以需要求余运算,使之变为空间上的循环
            //例如rear=7,7+1=8,8%8=0,此时空间上rear与front指向同一位置
            return true;
        }
        return false;
    }
    //判断是否为空
    public boolean isEmpty(){
        return this.front == this.rear;
    }
    //入队
    public void push(int val){
        if(isFull()){
            return;
        }
        this.elem[this.rear] = val;
        this.rear = (this.rear+1)%this.allSize;//用取余运算使rear指向空间的下一个位置
        this.useSize++;
    }

    //出队
    public void pop(){
        if(isEmpty()){
            return;
        }
        this.elem[this.front] = -1;//出队位置的值置为-1
        this.front = (this.front+1)%this.allSize;
        this.useSize--;
    }

    //得到队头元素
    public int getTop(){
        if(isEmpty()){
            return -1;
        }
        return this.elem[this.front];
    }
    //show
    public void show(){
        for(int i = this.front;i < this.rear;i = (i+1)%this.allSize){
            System.out.print(this.elem[i]+" ");
        }
        System.out.println();
    }
}

public class TestCQDemo {

    public static void main(String[] args) {
        QueueLink q1 = new QueueLink();
        for(int i=3;i<10;i++){
            q1.push(i);
        }
        System.out.println("判断循环队列是否已满:"+q1.isFull());
        System.out.print("循环入队后队列内元素:");    
        q1.show();
        System.out.print("出队后队列内元素:");
        q1.pop();
        q1.show();
        System.out.println("队头元素为:"+q1.getTop());
    }

}

运行结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/mars1997/article/details/80255538