java 线性表

线性表


java很多包装类已经实现了很多数据结构,为什么我们还要学会自己来实现呢?

  • 因为 java 给封装好的数据结构为了保证代码的通用性,所以比较臃肿 。
  • 在实际的开发需求中,封装的数据结构有可能不能满足我们特殊场景的要求。
  • 这时候,如果我们能自己实现这些数据结构,那么既可以提升效率,也可以更加贴合实际应用场景,灵活性更高。

1、顺序表

底层数据结构:数组

时间复杂度:

  • 查找:O(1)
  • 插入:O(n)
  • 删除:O(n)

具体实现:

public class SequenceList<T> implements Iterable{

    //存储元素的数组
    private T[] eles;
    //记录当前顺序表中的元素个数
    private int N;

    //构造方法,初始化数据
    public SequenceList(int capacity){
        this.eles = (T[])new Object[capacity];
        this.N = 0;
    }

    //将一个线性表置为空表
    public void clear(){
        this.N = 0;
    }

    //判断当前线性表是否为空表
    public boolean isEmpty(){
        return this.N==0;
    }

    //获取线性表的长度
    public int length(){
        return this.N;
    }

    //获取指定位置的元素
    public T get(int i){
        return eles[i];
    }

    //向线性表中添加元素
    public void insert(T t){
        //如果原来数组不够放了就扩容
        if (eles.length == N){
            resize(2*N);
        }
        //将元素放到数组末尾,数组长度加一
        eles[N++] = t;
    }

    //向线性表指定位置添加元素
    public void insert(int i, T t){
        //如果原来数组不够放了就扩容
        if (eles.length == N){
            resize(2*N);
        }
        //指定位置及其后边的元素都后移一位
        for(int index=N; index>i; index--){
            eles[index] = eles[index-1];
        }
        //把要插入的元素放到指定位置,数组长度加一
        eles[i] = t;
        this.N++;
    }

    //删除指定位置的元素
    public T remove(int i){
        //缩容
        if (N <= eles.length/4){
            resize(N/2);
        }
        //先保存要删除的元素
        T tmp = eles[i];
        //从该位置开始,后一个元素前移,数组长度减一
        for (int index=i; index<N-1; index++){
            eles[index] = eles[index+1];
        }
        N--;
        return tmp;
    }

    //查找元素第一次出现的位置
    public int indexOf(T t){
        for (int i = 0; i < this.N; i++) {
            if (t.equals(eles[i])){
                return i;
            }
        }
        return -1;
    }

    @Override
    public Iterator iterator() {
        return new SIterator();
    }

    private class SIterator implements Iterator{

        private int cusor;

        public SIterator(){
            cusor = 0;
        }

        @Override
        public boolean hasNext() {
            return cusor < N;
        }

        @Override
        public Object next() {
            return eles[cusor++];
        }
    }

    //调整数组的大小
    private void resize(int newSize){
        //保存原来数组的信息
        T[] temp = eles;
        //重新new空间
        eles = (T[])new Object[newSize];
        //把原来数组的信息保存进新建的空间里
        for (int i=0; i<N; i++){
            eles[i] = temp[i];
        }
    }

    //测试
    public static void main(String[] args) {
        SequenceList<String> list = new SequenceList<>(1);
        list.insert("lk");
        list.insert("hzz");
        list.insert("kk");

        list.insert(1,"wyj");
        System.out.println("下标为0的是:"+list.get(0));
        list.remove(2);

        for (Object s : list){
            System.out.println(s);
        }

        list.clear();
        System.out.println("数组长度为"+list.length());
    }
}

2、单向链表

Node

  • T item 存储实际的内容
  • Node next 指向下一个结点的指针

LinkList

  • Node head 头结点(item始终为null,next初始化为空)
  • int N (用来存放链表的实际长度)

具体实现:

public class SequenceList<T> implements Iterable{

    //存储元素的数组
    private T[] eles;
    //记录当前顺序表中的元素个数
    private int N;

    //构造方法,初始化数据
    public SequenceList(int capacity){
        this.eles = (T[])new Object[capacity];
        this.N = 0;
    }

    //将一个线性表置为空表
    public void clear(){
        this.N = 0;
    }

    //判断当前线性表是否为空表
    public boolean isEmpty(){
        return this.N==0;
    }

    //获取线性表的长度
    public int length(){
        return this.N;
    }

    //获取指定位置的元素
    public T get(int i){
        return eles[i];
    }

    //向线性表中添加元素
    public void insert(T t){
        //如果原来数组不够放了就扩容
        if (eles.length == N){
            resize(2*N);
        }
        //将元素放到数组末尾,数组长度加一
        eles[N++] = t;
    }

    //向线性表指定位置添加元素
    public void insert(int i, T t){
        //如果原来数组不够放了就扩容
        if (eles.length == N){
            resize(2*N);
        }
        //指定位置及其后边的元素都后移一位
        for(int index=N; index>i; index--){
            eles[index] = eles[index-1];
        }
        //把要插入的元素放到指定位置,数组长度加一
        eles[i] = t;
        this.N++;
    }

    //删除指定位置的元素
    public T remove(int i){
        //缩容
        if (N <= eles.length/4){
            resize(N/2);
        }
        //先保存要删除的元素
        T tmp = eles[i];
        //从该位置开始,后一个元素前移,数组长度减一
        for (int index=i; index<N-1; index++){
            eles[index] = eles[index+1];
        }
        N--;
        return tmp;
    }

    //查找元素第一次出现的位置
    public int indexOf(T t){
        for (int i = 0; i < this.N; i++) {
            if (t.equals(eles[i])){
                return i;
            }
        }
        return -1;
    }

    @Override
    public Iterator iterator() {
        return new SIterator();
    }

    private class SIterator implements Iterator{

        private int cusor;

        public SIterator(){
            cusor = 0;
        }

        @Override
        public boolean hasNext() {
            return cusor < N;
        }

        @Override
        public Object next() {
            return eles[cusor++];
        }
    }

    //调整数组的大小
    private void resize(int newSize){
        //保存原来数组的信息
        T[] temp = eles;
        //重新new空间
        eles = (T[])new Object[newSize];
        //把原来数组的信息保存进新建的空间里
        for (int i=0; i<N; i++){
            eles[i] = temp[i];
        }
    }

    //测试
    public static void main(String[] args) {
        SequenceList<String> list = new SequenceList<>(1);
        list.insert("lk");
        list.insert("hzz");
        list.insert("kk");

        list.insert(1,"wyj");
        System.out.println("下标为0的是:"+list.get(0));
        list.remove(2);

        for (Object s : list){
            System.out.println(s);
        }

        list.clear();
        System.out.println("数组长度为"+list.length());
    }
}

1) 快慢指针

两个指针:

  • 慢指针,每次只走到下一个结点
  • 快指针,每次走的是慢指针的两倍

可以解决的问题:

  • 求链表中间值
  • 判断链表中是否有环
  • 判断链表中的环的入口地址

具体实现:

//快慢指针可以解决的问题
public class QSPointer {

    //Node结点
    private static class Node<T>{
        T item;
        Node next;
        public Node(T item, Node next){
            this.item = item;
            this.next = next;
        }
    }

    //问题一:获取链表的中间值
    //原理:慢指针一次走一步,而快指针每次走的是慢指针的两倍,当快指针走到链表
    //最后一个结点时,慢指针刚好到达链表的中部
    public static String getMid(Node<String> head){
        //定义两个指针
        Node<String> fast = head;
        Node<String> slow = head;
        //遍历两个指针
        while (fast != null && fast.next !=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow.item;
    }

    //问题二:可以判断链表是否有环
    //原理:慢指针一次走一步,快指针一次走两步,如果快指针可以和慢指针相遇,那么
    //说明这个链表是有环的
    public static boolean hasLoop(Node<String> head){
        //定义两个指针
        Node<String> fast = head;
        Node<String> slow = head;
        //遍历两个指针
        while (fast != null && fast.next !=null){
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow){
                return true;
            }
        }
        return false;
    }

    //问题三:找到环的入口元素
    //原理:当快慢指针相遇的时候,额外定义一个指针,走的速度和慢指针一样,当额外
    //的指针和慢指针相遇的地方,就是环的入口
    public static String getEntrance(Node<String> head){
        //定义三个指针
        Node<String> fast = head;
        Node<String> slow = head;
        Node<String> temp = null;
        //遍历两个指针
        while (fast != null && fast.next !=null){
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow){
                temp = head;
                continue;
            }
            if (temp != null){
                temp = temp.next;
                if (temp == slow){
                    return temp.item;
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {
        Node<String> seven = new Node<>("gg",null);
        Node<String> six = new Node<>("ff",seven);
        Node<String> five = new Node<>("ee",six);
        Node<String> four = new Node<>("dd",five);
        Node<String> three = new Node<>("cc",four);
        Node<String> two = new Node<>("bb",three);
        Node<String> one = new Node<>("aa",two);

        System.out.println("中间值是:"+getMid(one));

        seven.next = three;
        System.out.println("链表是否有环:"+hasLoop(one));

        System.out.println("链表环的入口是:"+getEntrance(one));
    }
}

2) 有序符号表

存储key-value键值对,在插入的时候是有序插入的。

具体实现:

public class SymbolTable <Key extends Comparable<Key>, Value> {

    //记录首结点
    private Node<Key, Value> head;

    //记录符号表中键值对的个数
    private int N;

    //构造方法
    public SymbolTable(){
        head = new Node(null,null,null);
        N = 0;
    }

    //结点类
    private class Node<Key, Value>{
        public Key key;
        public Value value;
        public Node<Key, Value> next;
        public Node(Key key, Value value, Node next){
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }

    //根据键key,找对应的值
    public Value get(Key key){
        Node<Key, Value> node = head;
        while (node.next != null){
            node = node.next;
            if (node.key.equals(key)){
                return node.value;
            }
        }
        return null;
    }

    //向符号表中插入一个键值对
    public void put(Key key, Value value){
        Node<Key, Value> curr = head.next;
        Node<Key, Value> pre = head;
        while(curr!=null && key.compareTo(curr.key) > 0){
            pre = curr;
            curr = curr.next;
        }
        if (curr!=null && key.compareTo(curr.key)==0){
            curr.value = value;
            return;
        }
        Node newNode = new Node(key, value, curr);
        pre.next = newNode;
        N++;
    }

    //删除键为key的键值对
    public void delete(Key key){
        if (N==0){
            return;
        }
        Node<Key, Value> n = head;
        while (n.next!=null){
            if (n.next.key.equals(key)){
                n.next = n.next.next;
                N--;
                return;
            }
            n = n.next;
        }
    }

    //获取符号表的大小
    public int Size(){
        return N;
    }

    //测试
    public static void main(String[] args) {
        SymbolTable<Integer, String> table = new SymbolTable<>();
        table.put(1,"早起");
        table.put(2,"运动");
        table.put(3,"冥想");
        table.put(9,"读书");

        table.put(7,"睡觉");
    }
}

3、双向链表

Node

  • T item 存储实际的内容
  • Node pre 指向上一个结点的指针
  • Node next 指向下一个结点的指针

LinkList

  • Node first 头结点(pre始终为null, item始终为null,next初始化为空)
  • Node last 尾结点(初始化为null)
  • int N (用来存放链表的实际长度)

具体实现:

public class TwoWayLinkList<T> implements Iterable{
    //头结点
    private Node first;
    //尾结点
    private Node last;
    //链表长度
    private int N;

    @Override
    public Iterator iterator() {
        return new TwoIterator();
    }

    private class TwoIterator implements Iterator{

        private Node n;
        public TwoIterator(){
            n = first;
        }

        @Override
        public boolean hasNext() {
            return n.next!=null;
        }

        @Override
        public Object next() {
            n = n.next;
            return n.item;
        }
    }

    //内部结点类
    private class Node{
        public T item;
        public Node pre;
        public Node next;

        public Node(Node pre, T item,Node next){
            this.pre = pre;
            this.item = item;
            this.next = next;
        }
    }

    //构造方法
    public TwoWayLinkList(){
        //初始化头结点
        this.first = new Node(null, null,null);
        //初始化尾结点
        this.last = null;
        //初始化链表长度
        this.N = 0;
    }

    //空置线性表
    public void clear(){
        this.first.item = null;
        this.first.next = null;
        this.first.pre = null;
        this.last = null;
        this.N = 0;
    }

    //判断线性表是否为空
    public boolean isEmpty(){
        return this.N==0;
    }

    //获取线性表中元素的个数
    public int length(){
        return this.N;
    }

    //获取第一个元素
    public T getFirsht(){
        if (isEmpty()){
            return null;
        }
        return first.next.item;
    }

    //获取最后一个元素
    public T getLast(){
        if (isEmpty()){
            return null;
        }
        return last.item;
    }

    //读取并返回线性表中的第i个元素的值
    public T get(int i){
        if (i >= N || i < 0){
            return null;
        }
        //可以判断下 i 到头结点近还是到尾结点近
        Node n;
        if ((N-i)>=(i+1)){
            n = first;
            for (int index=0; index<=i; index++){
                n = n.next;
            }
        }else{
            n = last;
            for (int index=0; index<N-1-i; index--){
                n = n.pre;
            }
        }
        return n.item;
    }

    //往线性表中添加一个元素
    public  void insert(T t){
        if (isEmpty()){
            //如果链表为空
            Node n = new Node(first,t,null);
            first.next = n;
            last = n;
        }else {
            //如果链表不为空
            Node n = last;
            Node newNode = new Node(n,t,null);
            n.next = newNode;
            last = newNode;
        }
        N++;
    }

    //在线性表的第i个元素之前插入一个值为t的数据元素
    public void insert(int i, T t){
        if (i >= N || i < 0){
            return;
        }
        Node pre;
        //判断是从头往后找快还是从后往前找快
        if ((N-i)>=(i+1)){
            pre = first;
            for (int index=0; index<=i-1; index++){
                pre = pre.next;
            }
        }else{
            pre = last;
            for (int index=0; index<N-2-i; index++){
                pre = pre.pre;
            }
        }
        Node curNode = pre.next;
        Node newNode = new Node(pre, t, curNode);
        pre.next = newNode;
        curNode.pre = newNode;
        N++;
    }

    //删除并返回线性表中第i个数据元素
    public T remove(int i){
        if (i>=N || i<0){
            return null;
        }
        Node pre;
        //判断是从头往后找快还是从后往前找快 N=4 i=2
        if ((N-i)>=(i+1)){
            pre = first;
            for (int index=0; index<=i-1; index++){
                pre = pre.next;
            }
        }else{
            pre = last;//3
            for (int index=0; index<N-i; index++){
                pre = pre.pre;
            }
        }
        Node curNode = pre.next;
        if (!curNode.equals(last)){
            Node laterNode = curNode.next;
            pre.next = laterNode;
            laterNode.pre = pre;
        }else{
            pre.next = null;
            if (pre.equals(first)){
                last = null;
            }else{
                last = pre;
            }
        }

        N--;
        return curNode.item;
    }

    //返回线性表中首次出现的指定的数据元素的位序号,若不存在,则返回-1
    public int indexOf(T t){
        Node tmp = first;
        for (int index=0; tmp.next!=null; index++){
            tmp = tmp.next;
            if (tmp.item.equals(t)){
                return index;
            }
        }
        return -1;
    }

    //测试
    public static void main(String[] args) {
        TwoWayLinkList<String> list = new TwoWayLinkList<>();
        list.insert("lk");
        System.out.println("链表是不是空的:"+list.isEmpty());
        list.insert("hzz");
        list.insert("kk");

        list.insert(2,"wyj");

        for (Object s : list){
            System.out.println(s);
        }
        System.out.println("第一个:"+list.getFirsht());
        System.out.println("最后一个:"+list.getLast());
        System.out.println("下标为0的是:"+list.get(0));
        list.remove(2);

        for (Object s : list){
            System.out.println(s);
        }
        System.out.println("链表长度为"+list.length());
        System.out.println("下标为2的值是:"+list.get(2));
        list.clear();
        System.out.println("清空后链表长度为"+list.length());
    }
}

5、循环链表

public class JosephProblem {

    //内部结点类
    private static class Node<T>{
        public T item;
        public Node next;

        public Node(T item, Node next){
            this.item = item;
            this.next = next;
        }
    }


    //约瑟夫问题:有41个人围成一个圈,第一个人从1开始报数,报到3,这个人就godie,然后下一个再从1开始报数
    //直到所有人godie。约瑟夫和朋友不想godie,于是约瑟夫让他自己和朋友分别选择16和31的位置。
    public static void main(String[] args) {
        //1.创建循环链表
        Node<Integer> first = new Node<>(1,null);
        Node<Integer> pre = new Node<>(null,null);

        for (int i = 1; i <= 41; i++) {
            if (i==1){
                pre = first;
                continue;
            }
            Node<Integer> newNode = new Node<>(i, null);
            pre.next = newNode;
            pre = newNode;
            if (i == 41){
                pre.next = first;
            }
        }

        //2.创建一个计数器
        int counts = 0;
        Node n = first;
        Node preNode = null;
        //3.遍历循环链表
        while(n.next != n){
            counts++;
            if (counts == 3){
                //删除该结点
                preNode.next = n.next;
                counts = 0;
                System.out.print(n.item+" ");
                n = n.next;
            }else{
                //计数器加一,结点往后移
                preNode = n;
                n = n.next;
            }
        }
        System.out.print(n.item);
    }
}

6、栈

可以使用数组实现,也可以使用链表实现,这里采用的是链表实现。

栈的特点是:先进后出。

入栈:新建一个结点放到head结点后边

出栈:head结点的下一个结点出栈

具体实现:

public class Stack<T> implements Iterable{
    //头结点
    private Node head;
    //链表长度
    private int N;

    public Stack(){
        head = new Node(null,null);
        N = 0;
    }

    @Override
    public Iterator iterator() {
        return new SIterator();
    }


    private class SIterator implements Iterator{

        private Node node;
        public SIterator(){
            node = head;
        }
        @Override
        public boolean hasNext() {
            return node.next!=null;
        }

        @Override
        public Object next() {
            node = node.next;
            return node.item;
        }
    }

    //内部结点类
    private  class Node<T>{
        public T item;
        public Node next;

        public Node(T item, Node next){
            this.item = item;
            this.next = next;
        }
    }

    //判断栈是否是空
    public boolean isEmpty(){
        return N==0;
    }

    //获取栈中元素的个数
    public int size(){
        return N;
    }

    //弹出栈顶元素
    public T pop(){
        //判断栈是不是空的
        if (isEmpty()){
            //如果是空的,返回null
            return null;
        }else {
            Node<T> node = head.next;
            //判断结点是不是只有一个
            if (N==1){
                head.next = null;
            }else{
                Node<T> firstNode = head.next.next;
                head.next = firstNode;
            }
            N--;
            return node.item;
        }
    }

    //向栈中压入元素t
    public void push(T t){
        //判断栈是不是空的
        if (isEmpty()){
            //如果是空的,直接把元素放到第一个位置
            Node<T> newNode = new Node<>(t, null);
            head.next = newNode;
        }else {
            //保存原来第一个位置的结点
            Node oldFirst = head.next;
            //新建一个结点
            Node<T> newNode = new Node<>(t, oldFirst);
            //头结点指向新结点
            head.next = newNode;
        }
        N++;
    }

    //测试
    public static void main(String[] args) {
        Stack<String> s = new Stack<>();
        s.push("我可以");
        s.push("我能够");
        s.push("一定行");
        s.push("相信你");
        for (Object str: s) {
            System.out.println(str);
        }
        System.out.println("弹出来的是:"+s.pop());
        System.out.println("弹出来的是:"+s.pop());
        System.out.println("弹出来的是:"+s.pop());
        System.out.println("栈的长度是:"+s.size());
        System.out.println("栈是不是空的:"+s.isEmpty());
        System.out.println("弹出来的是:"+s.pop());
        System.out.println("栈是不是空的:"+s.isEmpty());
    }
}

1) 括号匹配

如果是( 就入栈,如果是 )就出栈。

最后可能的结果有:

  • 左括号多 遍历完栈不为空
  • 右括号多 pop前栈已经空了
  • 匹配 pop前栈不为空,遍历完栈为空
public class BracketsMatch {
    public static void main(String[] args) {
        String str = "(上海((长安)))";
        boolean match = isMatch(str);
        System.out.println(str+"中的括号是否匹配:"+match);
    }


    //判断str中的括号是否匹配 有三种结果:匹配成功、左括号多、右括号多
    public static boolean isMatch(String str){
        //定义一个栈,用来保存左括号
        Stack<String> myStack = new Stack<>();
        //将传入的字符串解析成一个个的字符串
        //遍历字符串数组
        for (int i=0; i<str.length(); i++){
            String tmp = str.charAt(i)+"";
            //判断如果是左括号就入栈,如果是右括号就出栈
            if (tmp.equals("(")){
                myStack.push(tmp);
            }else if (tmp.equals(")")){
                String pop = myStack.pop();
                if (pop == null){
                    return false;
                }
            }
        }
        if (myStack.size()==0){
            return true;
        }
        //循环结束后判断栈是不是空,是空则匹配成功,不是空则匹配失败
        return false;
    }
}

2) 逆波兰表达式

public class ReversePolishNotation {

    public static void main(String[] args) {
        //中缀表达式 3*(17-15)+18/6 的逆波兰式表达式如下
        String[] notation = {"3","17","15","-","*","18","6","/","+"};
        int result = caculate(notation);
        System.out.println("逆波兰表达式的结果为:"+result);
    }


    public static int caculate(String[] notation){
        //定义一个栈,用于存放操作数
        Stack<String> myStack = new Stack<>();
        //遍历字符串数组
        for (int i=0; i<notation.length; i++){
            Integer p1;
            Integer p2;
            switch (notation[i]){
                //如果是+-*/ 则弹出栈顶的两个元素,并进行计算,结果再压入栈中
                case "+":
                    p1 = Integer.parseInt(myStack.pop());
                    p2 = Integer.parseInt(myStack.pop());
                    myStack.push(p2+p1+"");
                    break;
                case "-":
                    p1 = Integer.parseInt(myStack.pop());
                    p2 = Integer.parseInt(myStack.pop());
                    myStack.push(p2-p1+"");
                    break;
                case "*":
                    p1 = Integer.parseInt(myStack.pop());
                    p2 = Integer.parseInt(myStack.pop());
                    myStack.push(p2*p1+"");
                    break;
                case "/":
                    p1 = Integer.parseInt(myStack.pop());
                    p2 = Integer.parseInt(myStack.pop());
                    myStack.push(p2/p1+"");
                    break;
                default:
                    //如果是其他的直接入栈
                    myStack.push(notation[i]);
                    break;
            }
        }
        if (myStack.size() == 1){
            return Integer.parseInt(myStack.pop());
        }
        return -1;
    }

}

9、队列

同样可以用数组实现,也可以用链表实现,这里用链表实现。

队列的特点是:先进先出

入队:每次往链表最后插入元素

出队:每次head下一个元素出队

具体实现:

public class Queue <T> implements Iterable<T>{
    //当前队列的元素个数
    private int N;
    //记录首结点
    private Node head;
    //记录尾结点
    private Node last;

    public Queue(){
        this.head = new Node(null,null);
        this.last = null;
        this.N = 0;
    }

    @Override
    public Iterator<T> iterator() {
        return new QIterator();
    }

    private class QIterator implements Iterator<T>{

        private Node<T> node;
        public QIterator(){
            node = head;
        }

        @Override
        public boolean hasNext() {
            return node.next!=null;
        }

        @Override
        public T next() {
            node = node.next;
            return node.item;
        }
    }

    //结点类
    private class Node<T>{
        public T item;
        public Node next;
        public Node(T item,Node next){
            this.item = item;
            this.next = next;
        }
    }

    //判断队列是否为空
    public boolean isEmpty(){
        return N==0;
    }

    //获取队列中的元素个数
    public int size(){
        return N;
    }

    //从队列中拿出一个元素
    public T dequeue(){
        if (isEmpty()){
            return null;
        }
        Node<T> firstNode = head.next;
        if (N==1){
            head.next = null;
            last = null;
        }else{
            head.next = firstNode.next;
        }
        N--;
        return firstNode.item;
    }

    //往队列中插入一个元素
    public void enqueue(T t){
        //判断队列是不是空的,即last是不是null
        if (last == null){
            last = new Node(t,null);
            head.next = last;
        }else {
            Node oldNode = last;
            last = new Node(t, null);
            oldNode.next = last;
        }
        N++;
    }

    public static void main(String[] args) {
        Queue<String> q = new Queue<>();
        q.enqueue("你很棒!");
        q.enqueue("你最强!");
        q.enqueue("你最好!");
        q.enqueue("牛逼!");
        for (String str : q){
            System.out.println(str);
        }
        System.out.println("------------------------------------------");
        String result = q.dequeue();
        System.out.println("出队列的元素是:"+result);
        System.out.println("剩余的元素个数:"+q.size());
    }
}

posted @ 2021-07-08 08:48  随性0528  阅读(165)  评论(0)    收藏  举报