实现Java中的栈、堆和串

直接上代码!

这是队列

/**
 *  本类是队列的实现类
 *  什么是队列?
 *      1. 队列是特殊的单链表
 *      2. 队列是先进先初的单链表
 *      3. 队列的元素只能从一头按顺序添加 在另一头按顺序移出
 *   为什么要用单链表作为成员变量?
 *      因为队列是特殊的单链表,因此直接使用单链表作为元素进行处理
 *  队列的方法有哪些?
 *      add         增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常
 *      remove      移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
 *      element     返回队列头部的元素             如果队列为空,则抛出一个NoSuchElementException异常
 *      offer       添加一个元素并返回true       如果队列已满,则返回false
 *      poll        移除并返问队列头部的元素    如果队列为空,则返回null
 *      peek        返回队列头部的元素             如果队列为空,则返回null
 *      put         添加一个元素                      如果队列满,则阻塞
 *      take        移除并返回队列头部的元素     如果队列为空,则阻塞
 * @data2021/8/31,12:53
 * @authorsutinghu
 */
public class Queue<T> {

    private SingleLinkList<T> queue;

    Queue(){
        queue = new SingleLinkList<>();
    }

    public void put(T t){
        queue.linkToTail(t);
    }

    public T peek(){
        if (queue.size == 0){
            return null;
        }
        return queue.get(queue.size-1);
    }

    public T poll(){
        if (queue.size == 0){
            return null;
        }
        T value = queue.get(queue.size-1);
        queue.remove(queue.size-1);
        return value;
    }
    /**
     * 添加元素
     * @return
     */
    public boolean offer(T t){
        queue.linkToTail(t);
        return true;
    }

    /**
     * 添加元素
     * @param t
     */
    public void add(T t){
        queue.linkToTail(t);
    }

    public void remove(){
        queue.getFirst();
        queue.remove(queue.size-1);
    }

    public T element(){
        queue.getFirst();
        return queue.get(queue.size-1);
    }
}

这是栈

/**
 * 本类是栈的实现类
 *  为什么要有单链表成员变量
 *  *      用单链表实现栈的方法
 *  栈是单链表的特殊形式
 *      1. 只在链尾进行增加和删除
 *      2. 只能操作一个元素
 *  为什么要用抽象类
 *      1. 使用抽象类
 * @data2021/8/31,12:32
 * @authorSUTINGHU
 */
public class Stack<T>{

    private SingleLinkList<T> stack;

    /**
     * 构造方法
     */
    Stack(){
        stack = new SingleLinkList<>();
    }

    /**
     * 查看某个元素在栈中的位置
     * @param t
     * @return
     */
    public int search(T t){
        return stack.indexOf(t);
    }

    /**
     * 查看栈顶元素但不移除
     * @return
     */
    public T peek(){
        if (stack.size == 0){
            return null;
        }
        T value = stack.get(stack.size-1);
        return value;
    }

    /**
     * 是否为空
     * @return
     */
    public boolean isEmpty(){
        return stack.isEmpty();
    }

    /**
     *  压栈方法
     * @param t
     */
    public void push(T t){
        stack.linkToTail(t);
    }

    /**
     *  弹栈方法
     * @return
     */
    public T  pop(){
        stack.getFirst();
        T value = stack.get(stack.size-1);
        stack.remove(stack.size-1);
        return value;
    }

}

这是串

/**
 *  本类为串的实现类,对标Java中的String
 *  什么是串?
 *      串是指一个或多个序列的字符组成的有限序列,又被称为字符串
 *  为什么要实现Serializable?
 *      本来是可序列化的
 *  为什么要实现Comparable?
 *      Comparable是一个比较接口 规范所有的比较方法都使用一个入口
 *  为什么要实现CharSequence?
 *       charSequence描述的就是一个字符串,string等都以多个字符组成的串为处理单元进行处理
 *       但是这些处理单元的基本单元是字符 该接口就是规范了对字符的操作
 *       Java中的String、StringBuilder和StringBuffer都实现了该接口,该接口是统一的接口
 * @data2021/8/31,13:11
 * @authorsutinghu
 */
public class Strings
        implements Serializable,
        Comparable<Strings>,
        CharSequence {

    /**
     * 存储我们在处理字符过程中产生的字符集合
     */
    private final char value[];

    // 缓存字符串的哈希代码
    private int hash;

    // 兼容jdk 1.0.2 之后的所有版本
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     *      很多人不知道这字段是干嘛的,其实和transient一样都是控制字段的序列化的,
     *      * 只不过transient修饰的字段不被序列化,而serialPersistentFields数组里
     *      * 的字段需要序列化,如果某个字段在serialPersistentFields数组里,且被transient
     *      * 修饰,则以serialPersistentFields为准,serialPersistentFields优先级高于
     *      * transient。
     *      * 这里是一个空数组,所以String类的所有字段都不会序列化
     */
    private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];
    /**
     * 构造方法:开局就给你一个没有大小的字符
     */
    public Strings() {
        this.value = new char[0];
    }

    /**
     * 构造方法:把你用过的源字符串传进来 我给你初始化
     * @param original
     */
    public Strings(@NotNull Strings original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    public boolean isEmpty() {
        return value.length == 0;
    }

    /**
     * 构造方法:给我一个字符数据 我也能把它处理成为字符串
     * @param value
     */
    public Strings(@NotNull char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

    public Strings(@NotNull char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }

        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }

    /**
     * 获得字符串的长度
     * @return
     */
    @Override
    public int length() {
        return value.length;
    }

    /**
     * 获得某个位置的字符
     * @param index
     * @return
     */
    @Override
    public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }

    /**
     * 获取字符串
     * @param beginIndex
     * @param endIndex
     * @return
     */
    public Strings substring(int beginIndex, int endIndex) {

        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new Strings(value, beginIndex, subLen);
    }

    /**
     *  将一个开始和结束之间的字符返回出去
     * @param start
     * @param end
     * @return
     */
    @Override
    public CharSequence subSequence(int start, int end) {
        return this.substring(start, end);
    }

    /**
     * 两个字符串比较大小
     *      字符一样时越长越大
     *      字符不一样时,第一个字符越先越大
     *      使用的是自然朴素的模糊比较算法
     * @param o
     * @return
     */
    @Override
    public int compareTo(Strings o) {
        int len1 = value.length;
        int len2 = o.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = o.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

    /**
     * 跟另一个字符串作比较
     *      如果传入是值不是strings类型的值
     *          直接判断地址是否一样 一样时返回true
     *      如果传入的值是strings 则按字符比较是否一样
     *
     * @param anObject
     * @return
     */
    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof Strings) {
            Strings anotherString = (Strings)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i]){
                        return false;
                    }
                    i++;
                }
                return true;
            }
        }
        return false;
    }

}

请在【一曲阳关尽】回复线性表获取源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值