当前位置: 首页 > news >正文

【数据结构与算法】List接口栈队列

🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:数据结构与算法
🌠 首发时间:2022年9月17日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
🌟 一以贯之的努力 不得懈怠的人生

阅读指南

  • List 接口
  • ArrayList 和 LinkedList
  • Comparator接口
  • 线性表和合集的静态方法
  • 队列和优先队列
    • 将 LinkedList 作为队列使用
    • 实现栈和队列
    • 优先队列

List 接口

List 接口继承自 Collection 接口,其中定义了一个用于顺序存储元素的合集,我们可以使用它的两个具体类 ArrayList 或者 LinkedList 来创建一个线性表

方法名及返回类型描述
add(index: int, element: Object) : boolean在指定索引位置处增加一个新元素
addAll(index: int, c: Collection<? extends E>) : boolean在指定索引位置处添加 c 中的所有元素
get(index: int) : E返回该线性表指定索引位置处的元素
indexOf(element: Object) : int返回第一个匹配元素的索引
lastIndexOf(element: Object) : int返回最后一个匹配元素的索引
listIterator() : ListIterator<E>返回针对该线性表元素的迭代器
listIterator(startIndex: int) : ListIterator<E>返回针对从 startIndex 开始的元素的迭代器
remove(index: int) : E移除指定索引位置处的元素
set(index: int, element: Object) : Object设置指定索引处的元素
subList(fromIndex: int, toIndex: int) : List<E>返回从 fromIndextoIndex-1 的子线性表

ArrayList 和 LinkedList

数组线性表类 ArrayList 和链表类 LinkedList 是实现 List 接口的两个具体类

ArrayList 用数组存储元素,这个数组是动态创建的。如果元素个数超过了数组的容量,就创建一个更大的新数组,并将当前数组中的所有元素都复制到新数组中,而 LinkedList 则是在一个链表中存储元素

要选用这两种类中的哪一个依赖于特定需求。如果需要通过下标随机访问元素,而不会在线性表起始位置插入或删除元素,那么 ArrayList 提供了最高效率的合集。但是,如果应用程序需要在线性表的起始位置上插入或删除元素,就应该选择 LinkedList

ArrayList 的构造方法和其特有方法:

方法名描述
ArrayList()使用默认的初始容量创建一个空线性表
ArrayList(c: Collection<? extends E>)从已有的合集中创建一个线性表
ArrayList(initialCapacity: int)创建一个指定初始容量的空线性表
trimToSize() : void将该 ArrayList 实例的容量裁剪到该线性表当前大小

LinkedList 的构造方法和其特有方法:

方法名描述
LinkedList()创建一个默认的空线性表
LinkedList(c: Collection<? extends E>)从已有的合集种创建一个线性表
addFirst(o: E) : void添加元素到该线性表的头部
addLast(o: E) : void添加元素到该线性表的尾部
getFirst() : E返回该线性表的第一个元素
getLast() : E返回该线性表的最后一个元素
removeFirst() : E从线性表中返回并删除第一个元素
removeLast() : E从线性表返回并删除最后一个元素

我们写一个程序来感受一下:

import java.util.*;

public class TestArrayAndLinkedList {
    public static void main(String[] args) {
        List<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(0, 10);
        arrayList.add(3, 30);
        System.out.println("A list of integers in the array list:");
        System.out.println(arrayList);

        LinkedList<Object> linkedList = new LinkedList<>(arrayList);
        linkedList.add(1, "red");
        linkedList.removeLast();
        linkedList.addFirst("green");
        System.out.println("Display the linked list backward:");
        for (int i = linkedList.size() - 1; i >= 0; --i) {
            System.out.print(linkedList.get(i) + " ");
        }
    }
}

运行结果如下:

在这里插入图片描述

Comparator接口

Java API 的一些类,比如 StringDateCalendarBigIntegerBigDecimal 以及所有基本类型的数字包装类都实现了 Comparator 接口。Comparator 接口中定义了 compareTo 方法,用于比较实现了 Comparable 接口的同一个类的两个元素

如果元素的类没有实现 Comparable 接口又将如何呢?这些元素可以比较吗?我们可以定义一个比较器(Comparator)来比较不同类的元素。要做到这一点,需要创建一个实现 java.util.Comparator<T> 接口的类并重写它的 compare 方法

public int compare(T element1, T element2)

如果 element1 小于 element2,就返回一个负值;如果 element1 大于 element2,就返回一个正值;如果两者相等,则返回 0

线性表和合集的静态方法

Collections 类(不是 Collection接口)包含了执行合集和线性表中通用操作的静态方法

Collections 类包含用于线性表的 sortbinarySearchreverseshufflecopyfill 方法,以及用于合集的 maxmindisjointfrequency 方法,如下表所示

方法描述
sort(list: List) : void对指定的线性表进行排序
sort(list: List, c: Comparator) : void使用比较器对指定的线性表进行排序
binarySearch(list: List, key: Object) : int采用二分查找来找到排好序的线性表中的键值
binarySearch(list: List, key: Object, c: Comparator) : int使用比较器,采用二分查找来找到排好序的线性表中的键值
reverse(list: List) : void对指定的线性表进行逆序排序
reverseOrder() : Comparator返回一个逆序排序的比较器
shuffle(list: List) : void随机打乱指定的线性表
shuffle(list: List, rmd: Random) : void使用一个随机对象打乱指定的线性表
copy(des: List, src: List) : void复制源线性表到目标线性表中
nCopies(n: int, o: Object) : List返回一个由 n 个对象副本组成的线性表
fill(list: List, o: Object) : void使用对象填充线性表
max(c: Collection) : Object返回合集中的 max 对象
max(c: Collection, c: Comparator) : Object使用比较器返回 max 对象
min(c: Collection) : Object返回合集中的 min 对象
min(c: Collection, c: Comparator) : Object使用比较器返回 min 对象
disjoint(c1: Collection, c2: Collection) : boolean如果 c1 和 c2 没有共同的元素,则返回真
frequency(c: Collection, o: Object) : int返回合集中指定元素的出现次数

下面的代码是对线性表中的字符串进行排序:

import java.util.*;

public class test {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("red", "green", "blue");
        Collections.sort(list);
        System.out.println(list);
    }
}

执行结果如下:

在这里插入图片描述

如果想要降序排列,我们可以简单地使用 Collection.reverseOrder() 方法,它会返回一个 Comparator 对象,该方法以逆序排列元素,下面是一段简单的降序排列的代码:

import java.util.*;

public class test {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("red", "green", "blue");
        Collections.sort(list, Collections.reverseOrder());
        System.out.println(list);
    }
}

执行结果如下:

在这里插入图片描述

队列和优先队列

队列(queue)是一种先进先出的数据结构,元素被追加到队列末尾,然后从队列头删除。在优先队列(priority queue)中,元素被赋予优先级。当访问元素时,拥有最高优先级的元素最先被删除

将 LinkedList 作为队列使用

JFC 中并没有提供具体的队列类,而只是提供了 Queue 接口和 Deque 接口,而具体类 LinkedList 继承了 Deque 接口,而 Deque 接口又继承了 Queue 接口,事实上 LinkedList 可以作为队列使用

import java.util.*;

public class TestQueue {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        queue.offer("red");
        queue.offer("green");
        queue.offer("blue");
        queue.offer("cyan");

        while (queue.size() > 0) {
            System.out.print(queue.remove() + " ");
        }
    }
}

执行结果如下:

在这里插入图片描述

实现栈和队列

需求:

  • 实现栈 GenericStack
方法名描述
GenericStack()创建一个空的栈
getSize() : int返回栈中元素的数量
peek() : E返回栈顶的元素
pop() : E返回并删除栈顶的元素
push(o: E) : void往栈顶添加一个元素
isEmpty() : boolean如果栈为空,返回 true

具体代码如下:

import java.util.*;

public class GenericStack<E> {
    private final ArrayList<E> list;

    public GenericStack() {
        list = new ArrayList<>();
    }

    public int getSize() {
        return list.size();
    }

    public E peek() {
        return list.get(getSize() - 1);
    }

    public void push(E o) {
        list.add(o);
    }

    public E pop() {
        E o = list.get(getSize() - 1);
        list.remove(getSize() - 1);
        return o;
    }

    public boolean isEmpty() {
        return list.isEmpty();
    }
}
  • 实现队列 GenericQueue
方法名描述
enqueue(e: E) : void添加一个元素到队列中
dequeue() : E从队列中移除一个元素
getSize() : int返回队列中元素的数量

具体代码如下:

import java.util.*;

public class GenericQueue<E> {
    private final LinkedList<E> list;
    
    public GenericQueue() {
        list = new LinkedList<>();
    }

    public void enqueue(E e) {
        list.add(e);
    }

    public E dequeue() {
        return list.removeFirst();
    }

    public int getSize() {
        return list.size();
    }

    @Override
    public String toString() {
        return "GenericQueue{" +
                "list=" + list +
                '}';
    }
}

优先队列

PriorityQueue 类实现了一个优先队列,默认情况下,优先队列使用 Comparable 以元素的自然顺序进行排序,拥有最小数值的元素被赋予最高优先级,因此最先从队列中删除。如果几个元素具有相同的最高优先级,则任意选择一个,也可以使用构造方法 PriorityQueue(initialCapacity, comparator) 中的 Comparator 来指定一个顺序

方法名描述
PriorityQueue()创建一个初始容量为 11 的默认优先队列
PriorityQueue(initialCapacity: int)创建一个初始容量为指定值的默认优先队列
PriorityQueue(c: Collection<? extends E>)创建一个具有指定合集的优先队列
PriorityQueue(initialCapacity: int, comparator: Comparator<? super E>)创建一个初始容量为指定值并且具有比较器的优先队列

运行实例:

import java.util.*;

public class PriorityQueueDemo {
    public static void main(String[] args) {
        PriorityQueue<String> q1 = new PriorityQueue<>();
        q1.offer("red");
        q1.offer("green");
        q1.offer("blue");
        q1.offer("cyan");
        System.out.println("Priority queue using Comparable:");
        while (q1.size() > 0) {
            System.out.print(q1.remove() + " ");
        }
        System.out.println();

        PriorityQueue<String> q2 = new PriorityQueue<>(4, Collections.reverseOrder());
        q2.offer("red");
        q2.offer("green");
        q2.offer("blue");
        q2.offer("cyan");
        System.out.println("Priority queue using Comparator:");
        while (q2.size() > 0) {
            System.out.print(q2.remove() + " ");
        }
        System.out.println();
    }
}

运行结果如下:

在这里插入图片描述

相关文章:

  • 将cookie字符串转成editthiscookie插件的json格式
  • SpringAOP总结
  • python--数据容器--列表
  • Roson的Qt之旅 #119 QNetworkAddressEntry详细介绍
  • Mybatis -- 使用
  • C语言双链表,循环链表,静态链表讲解(王道版)
  • 比较zab、paxos和raft的算法的异同
  • Python Argparse 库讲解特别好的
  • C++~从编译链接的过程看为什么C++支持重载?externC有什么用?
  • App移动端测试【10】Monkey自定义脚本案例
  • springboot 整合dubbo3开发rest应用
  • 【机器学习】集成学习:使用scikitLearn中的BaggingClassifier实现bagging和pasting策略
  • 算法与数据结构 --- 串,数组和广义表 --- 串
  • 【Python Web】Flask框架(四)Bootstrap的使用及案例
  • MySQL------数据表的创建和简单、条件,模糊查询
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Flex布局到底解决了什么问题
  • JavaScript DOM 10 - 滚动
  • Laravel5.4 Queues队列学习
  • zookeeper系列(七)实战分布式命名服务
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 汉诺塔算法
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 检测对象或数组
  • 那些年我们用过的显示性能指标
  • 深入浅出Node.js
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 微信支付JSAPI,实测!终极方案
  • 学习使用ExpressJS 4.0中的新Router
  • Linux权限管理(week1_day5)--技术流ken
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (接口封装)
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (一)kafka实战——kafka源码编译启动
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)四层和七层负载均衡的区别
  • .net 4.0发布后不能正常显示图片问题
  • .NET DataGridView数据绑定说明
  • .net framework profiles /.net framework 配置
  • .Net 代码性能 - (1)
  • .NET序列化 serializable,反序列化
  • @JoinTable会自动删除关联表的数据
  • [ C++ ] 继承
  • [codevs 1515]跳 【解题报告】
  • [docker] Docker容器服务更新与发现之consul
  • [EFI]DELL XPS13 9360电脑 Hackintosh 黑苹果efi引导文件
  • [HEOI2013]ALO
  • [javaSE] 数据结构(二叉查找树-插入节点)
  • [leetcode] 66. 加一
  • [LeetCode] Copy List with Random Pointer 拷贝带有随机指针的链表
  • [Linux] MySQL数据库之索引