二、Java集合相关的数据结构(中)

 

目录

3.栈

4.队列


3.栈

(1)定义

栈是一种只能在一端进行插入或删除操作的线性表,因此根据存储结构的不同分为顺序栈和链栈。其中允许进行插入或删除操作的一端称为栈顶(top),栈顶由一个称为栈顶指针的位置指示器来指示,它是动态变化的。表的另一端称为栈底,栈底是固定不变的。栈的插入和删除操作一般称为入栈(push)和出栈(pop)。栈最主要的特点就是先进先出

(2)声明一个顺序栈

/**
 * 顺序栈
 */
public class SqStack<T> {

    private Object[] elementsData;//所有元素数据
    private int top;//栈顶指针(索引)

    //构造方法
    public SqStack(int capacity) {//规定栈的容量
        if (capacity < 1) throw new IllegalArgumentException();
        elementsData = new Object[capacity];
        top = -1;
    }

    //入栈
    public void push(T data){
        if(top==elementsData.length-1){
            System.out.println("栈已满");
            return;
        }
        elementsData[++top] = data;//入栈操作
    }

    //出栈
    public T pop(){
        if(top==-1){
            System.out.println("栈已空");
            return null;
        }
        return (T)elementsData[top--];//出栈操作
    }
}

(3)声明一个链栈

/**
 * 链栈
 */
public class LinkStack<E> {
    /**
     * 声明链栈结点
     */
    private class LNode{
        private E data;//结点数据
        private LNode next;//结点的后继结点地址

        //构造方法
        private LNode(){}
    }

    private LNode top;//栈顶指针

    public LinkStack(){//链栈随机开辟内存空间,不会栈满
    }

    //入栈:头插法
    public void push(E data){
        LNode lNode = new LNode();//申请新结点
        lNode.data = data;
        lNode.next = top;
        top = lNode;
    }

    //出栈
    public E pop(){
        if(top==null){
            System.out.println("栈已空");
            return null;
        }
        E temp = top.data;
        top = top.next;
        return temp;
    }

}

4.队列

(1)定义

队列同栈一样,也是一种操作受限的线性表,其被限制为仅允许在表的一端进行插入,在表的另一端进行删除。可进行插入的一端称为队尾(rear),可进行删除的一端称为队头(front)。向队尾插入元素称为入队(enQueue),从队头删除元素称为出队(deQueue)。队列的主要特点是先进先出

(2)声明一个顺序循环队列

假溢出:在顺序队中,元素入队rear指针向后移,元素出队front指针向后移,经过一系列操作之后,两个指针可能同时指向数组末尾。此时虽然队列为空,但却无法让元素入队,这就是所谓的假溢出。

那么假溢出应该如何解决呢?此时可以把数组在逻辑上变成一个环,这样就不会出现假溢出的情况。但此时又出现了一个新的问题,元素空与满的时候,均是两个指针重合,因此只能损失一个空间,使得空的时候指针重合,满的时候指针间隔一个空元素,这样就完美解决了假溢出的问题。

/**
 * 顺序循环队列
 */
public class SqQueue<E> {
    private Object[] elemnetsData;//所有元素数据
    private int front;//队头
    private int rear;//队尾

    //构造方法
    public SqQueue(int capacity) {
        if (capacity < 1) throw new IllegalArgumentException();
        //循环队列浪费一个空间
        elemnetsData = new Object[capacity + 1];
    }

    //入队
    public void enQueue(E data) {
        if ((rear + 1) % elemnetsData.length == front) {
            System.out.println("队列已满");
            return;
        }
        rear = (rear + 1) % elemnetsData.length;//尾指针后移
        elemnetsData[rear] = data;
    }

    //出队
    public E deQueue() {
        if (rear == front) {
            System.out.println("队列已空");
            return null;
        }
        front = (front + 1) % elemnetsData.length;//头指针后移
        E temp = (E) elemnetsData[front];
        elemnetsData[front] = null;
        return temp;
    }
}

(3)声明一个链队

/**
 * 链队
 */
public class LinkQueue<E> {
    /**
     * 声明链队的结点
     */
    private class LNode {
        private E data;//结点数据
        private LNode next;//结点的后继结点地址

        //构造方法
        private LNode() {
        }
    }

    private LNode front;//头指针
    private LNode rear;//尾指针

    //构造方法
    public LinkQueue() {
    }

    //入队:头插法
    public void enQueue(E data) {
        LNode lNode = new LNode();
        lNode.data = data;
        //队列为空时需要特殊处理
        if (rear == null) {
            rear = lNode;
            front = lNode;
        }
        rear.next = lNode;
        rear = lNode;
    }

    //出队
    public E deQueue() {
        if (rear == null) {
            System.out.println("队列已空");
            return null;
        }
        E temp = front.data;
        front = front.next;//队头指针后移
        //队列为空时需要特殊处理
        if (front == null) rear = null;
        return temp;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值