常用数据结构一览

程序 = 算法 + 数据结构

操作数据的增、删、改、查、排序及相关的逻辑运算都要基于数据结构

下面简单罗列下常用的一些数据结构

 

                                                       数据结构简单分类

1. 数组(Array,ArrayList)

创建数组必须明确指定数组的长度,并且需要分配一段连续的存储空间

数组既然是定长的,就会遇到需要动态扩容的情况,通常通过复制原数组实现:

Arrays.copyOf(elementData, size, Object[].class);

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

集合中的ArrayList就是基于数组特性实现的,因此是有序的,数据元素允许重复。

ArrayList 随机读取元素很方便,但是在操作加减元素时,重新排序索引比较浪费性能。

2.链表(LinkedList)

链表分单链表、双链表、环链表

                                                                链表

链表是由指针控制数据节点与节点之间的关联关系,由于存在指针存储区,因此数据存储密度要低于ArrayList, 并且空间存储上是不连续的,因此是不能像ArrayList那样通过集合下标随机获取元素,即LinkedList存储的元素是无序的,数据元素不允许重复。

ArrayList 与 LinkedList使用场景取舍:
频繁读取修改元素,宜用ArrayList; 频繁加减元素,宜用LinkedList

3.队列(Queue)

先进先出(FIFO),从队列尾部添加,从头部查询或删除

Queue 继承于Collection类,因此有集合通用的add(), remove()方法

常用实现类:

(1)ConcurrentLinkedQueue 线程安全的队列

offer(); // 加入元素

peek(); // 获取队列头部第一个元素

poll();  // 获取队列头部第一个元素,并从队列中移除

下面说下阻塞队列:

(2)ArrayBlockingQueue 有界队列

基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,其内部没实现读写分离,也就意味着生产和消费不能完全并行,长度是需要定义的,可以指定先进先出或者先进后出,也叫有界队列,在使用该队列时必须指定队列的容量大小

// 超时未添加成功返回false, 该方法优于add()方法
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;

(3)LinkedBlockingQueue 无界队列

可以不设置队列的长度,若指定了长度则同有界队列

(4)SynchronousQueue 不能存储元素,即时处理

(5)PriorityBlockingQueue 

基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定,也就是说传入队列的对象必须实现Comparable接口),在实现PriorityBlockingQueue时,内部控制线程同步的锁采用的是公平锁,他也是一个无界的队列。

(6)DelayQueue

带有延迟时间的Queue,其中的元素只有当其指定的延迟时间到了,才能够从队列中获取该元素。DelayQueue中的元素必须实现Delayed接口,DelayQueue是一个没有大小限制的队列,应用场景很多,比如对缓存超时的数据进行移除、任务超时处理、空闲连接的关闭等等。

                                                        队列应用场景

4.双端队列(Deque)

可以在队列的首尾两端操作添加,删除,查询。

举一个应用场景,比如我们可以控制双端队列一端生产,一端消费

5.栈(Stack)

限制队列只能在一端操作,就成了栈,特点是后进先出(Last Input First Output)

                                       

                                                       栈-LIFO

6.树

树,最基本的就是二叉树,由此可以演变出平衡二叉树,满二叉树,完全二叉树,斜树,

红黑树(通过旋转及变换,追求局部平衡),

BTree(多阶树,节点存储 索引+数据,不满足单一原则,稳定性下降),

                                                                        B树

                                                                       B+树

哈夫曼树(最优树,就是指带权路径最小的树,仅包含度为0或者2的节点)

森林(一棵树为树,两棵树及以上则称为森林)

树一般设计的算法思想就是 递归

树的遍历

(1) 前序遍历(Preorder Traversal) 输出:ABDHIEJCFG

方法:先访问根节点,然后访问左子树,最后访问右子树。在访问左、右子树的时候,同样,先访问子树的根节点,再访问子树根节点的左子树和右子树,这是一个不断递归的过程。

应用场景:运用最多的场合包括在树里进行搜索以及创建一棵新的树。

(2)中序遍历(Inorder Traversal)输出:HDIBJEAFCG

方法:先访问左子树,然后访问根节点,最后访问右子树,在访问左、右子树的时候,同样,先访问子树的左边,再访问子树的根节点,最后再访问子树的右边。

应用场景:最常见的是二叉搜索树,由于二叉搜索树的性质就是左孩子小于根节点,根节点小于右孩子,对二叉搜索树进行中序遍历的时候,被访问到的节点大小是按顺序进行的。

(3) 后序遍历(Postorder Traversal)输出:HIDJEBFGCA

方法:先访问左子树,然后访问右子树,最后访问根节点。

应用场景:在对某个节点进行分析的时候,需要来自左子树和右子树的信息。收集信息的操作是从树的底部不断地往上进行。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值