数据结构小结 (集合部分) (Java)

一.认识集合框架

1.1 什么是集合框架

Java 集合框架 Java Collection Framework ,又被称为容器 container ,是定义在 java.util 包下的一组接口 interfaces 和其实现类 classes 。

其主要表现为将多个元素 element 置于一个单元中,用于对这些元素进行快速、便捷的存储 store 、检索 retrieve 、 管理 manipulate ,即平时我们俗称的增删查改 CRUD 。

类和接口总览

1.2 背后所涉及的数据结构以及算法

Collection:是一个接口,包含了大部分容器常用的一些方法

List:是一个接口,规范了ArrayList 和 LinkedList中要实现的方法

ArrayList:实现了List接口,底层为动态类型顺序表

LinkedList:实现了List接口,底层为双向链表

Stack:底层是栈,栈是一种特殊的顺序表

Queue:底层是队列,队列是一种特殊的顺序表

Deque:是一个接口

Set:集合,是一个接口,里面放置的是K模型

HashSet:底层为哈希桶,查询的时间复杂度为O(1)

TreeSet:底层为红黑树,查询的时间复杂度为O( ),关于key有序的

Map:映射,里面存储的是K-V模型的键值对

HashMap:底层为哈希桶,查询时间复杂度为O(1)

TreeMap:底层为红黑树,查询的时间复杂度为O( ),关于key有序


二.时间和空间复杂度

2.1 时间复杂度

1.定义:算法中的基本操作的执行次数,为算法的时间复杂度

2.大O的渐进表示法

实际中计算时间复杂度时,其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。

如何推导?

1、用常数1取代运行时间中的所有加法常数。

2、在修改后的运行次数函数中,只保留最高阶项。

3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。 

例如

void func2(int N) {
int count = 0;
for (int k = 0; k < 2 * N ; k++) {
count++;
}
int M = 10;
while ((M--) > 0) {
count++;
}
System.out.println(count);
}

基本操作执行了2N+10次,通过推导大O阶方法知道,时间复杂度为 O(N)

2.2 空间复杂度

1.定义:临时占用存储空间大小的量度


三.包装类&简单认识泛型

2.1 包装类

在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了 一个包装类型。

基本数据类型和对应的包装类

2.2 泛型

1.定义:泛型是在JDK1.5引入的新的语法,通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。就是指定当前的容器,要持有什么类型的对象。让编译器去做检查。

2.语法:

class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}

3. 泛型的上界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束

class 泛型类名称<类型形参 extends 类型边界> {
...
}
public class MyArray<E extends Number> {
...
}

4.泛型方法

//方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }
public class Util {
//静态的泛型方法 需要在static后用<>声明泛型类型参数
public static <E> void swap(E[] array, int i, int j) {
E t = array[i];
array[i] = array[j];
array[j] = t;
}
}

四.List的介绍

4.1 什么是List

List是一个接口继承自Collection ,即n个具有相同类型元素的有限序列,在该序列上可以执行增删 改查以及变量等操作。

(Collection也是一个接口,该接口中规范了后序容器中常用的一些方法)

4.2 2. 常见接口

boolean add(E e) 尾插 e

void add(int index, E element) 将 e 插入到 index 位置

boolean addAll(Collection c) 尾插 c 中的元素 E

remove(int index) 删除 index 位置元素

boolean remove(Object o) 删除遇到的第一个 o

E get(int index) 获取下标 index 位置元素 E

set(int index, E element) 将下标 index 位置元素设置为 element

void clear() 清空

boolean contains(Object o) 判断 o 是否在线性表中

int indexOf(Object o) 返回第一个 o 所在下标

int lastIndexOf(Object o) 返回最后一个 o 的下标

List subList(int fromIndex, int toIndex) 截取部分 list


五.ArrayList与LinkList

5.1 ArrayList

1.定义:用一段物理地址连续的存储单元依次存储数据元素的线性结构

2.构造:

ArrayList() 无参构造

ArrayList(Collection c) 利用其他 Collection 构建

ArrayList ArrayList(int initialCapacity) 指定顺序表初始容量

3.常见操作:

boolean add(E e) 尾插 e

void add(int index, E element) 将 e 插入到 index 位置

boolean addAll(Collection c) 尾插 c 中的元素 E

remove(int index) 删除 index 位置元素

boolean remove(Object o) 删除遇到的第一个 o

E get(int index) 获取下标 index 位置元素

E set(int index, E element) 将下标 index 位置元素设置为 element

void clear() 清空 boolean contains(Object o) 判断 o 是否在线性表中

int indexOf(Object o) 返回第一个 o 所在下标

int lastIndexOf(Object o) 返回最后一个 o 的下标

List subList(int fromIndex, int toIndex) 截取部分 list

4.ArrayList的遍历

ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器

5.ArrayList的扩容机制

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。

5.2 LinkList

1.定义:LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,元素存储在单独的节 点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元素时,不需要搬移元素,效率比较高

2.构造:

LinkedList() 无参构造

public LinkedList(Collection c) 使用其他集合容器中元素构造List

3.常见操作:

boolean add(E e) 尾插 e

void add(int index, E element) 将 e 插入到 index 位置

boolean addAll(Collection c) 尾插 c 中的元素 E

remove(int index) 删除 index 位置元素

boolean remove(Object o) 删除遇到的第一个 o

E get(int index) 获取下标 index 位置元素

E set(int index, E element) 将下标 index 位置元素设置为 element

void clear() 清空

boolean contains(Object o) 判断 o 是否在线性表中

int indexOf(Object o) 返回第一个 o 所在下标

int lastIndexOf(Object o) 返回最后一个 o 的下标

List subList(int fromIndex, int toIndex) 截取部分 list

ArrayList和LinkedList的区别

ArrayList物理上连续,而LinkList只在逻辑上连续

ArrayList的遍历速度是O(1),而LinkList是O(N)

ArrayList的插入速度是O(N),而LinkList是O(1)

ArrayList的空间不够时需要扩容,而LinkList不需要


六.栈和队列

6.1 栈

1.定义:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作

2.常见操作:

Stack() 构造一个空的栈

E push(E e) 将e入栈,并返回e

E pop() 将栈顶元素出栈并返回

E peek() 获取栈顶元素

int size() 获取栈中有效元素个数

boolean empty() 检测栈是否为空

6.2 队列

1.定义:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头

在Java中,Queue是个接口,底层是通过链表实现的。

2.基础操作:

boolean offer(E e) 入队列

E poll() 出队列

peek() 获取队头元素

int size() 获取队列中有效元素个数

boolean isEmpty() 检测队列是否为空

3.循环队列

实际中我们有时还会使用一种队列叫循环队列。如生产者消费者模型时可以就会使用循环队列。 环形队列通常使用数组实现

4.双端队列 (Deque)

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。 那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口。

Deque stack = new ArrayDeque<>();//双端队列的线性实现

Deque queue = new LinkedList<>();//双端队列的链式实现


七.二叉树

7.1 树

1.树的相关概念:

结点的度:一个结点含有子树的个数称为该结点的度;

树的度:一棵树中,所有结点度的最大值称为树的度;

叶子结点或终端结点:度为0的结点称为叶结点;

双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点;

孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点;

根结点:一棵树中,没有双亲结点的结点;

树的高度或深度:树中结点的最大层次;

非终端结点或分支结点:度不为0的结点; 

兄弟结点:具有相同父结点的结点互称为兄弟结点;

堂兄弟结点:双亲在同一层的结点互为堂兄弟;

结点的祖先:从根到该结点所经分支上的所有结点;

子孙:以某结点为根的子树中任一结点都称为该结点的子孙。

森林:由m(m>=0)棵互不相交的树组成的集合称为森林

2.树的应用

文件系统管理(目录和文件)

7.2 二叉树

1.定义:

一棵二叉树是结点的一个有限集合,该集合:

    1. 或者为空

    2. 或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

2.二叉树的遍历

// 前序遍历 void preOrder(Node root);根节点->左节点->右节点

// 中序遍历 void inOrder(Node root);左节点->根节点->右节点

// 后序遍历 void postOrder(Node root);左节点->右节点->根节点

3.层序遍历

从上到下,从左到右依次遍历

4.二叉树的基本操作

// 获取树中节点的个数 int size(Node root);

// 获取叶子节点的个数 int getLeafNodeCount(Node root);

// 子问题思路-求叶子结点个数

// 获取第K层节点的个数 int getKLevelNodeCount(Node root,int k);

// 获取二叉树的高度 int getHeight(Node root);

// 检测值为value的元素是否存在 Node find(Node root, int val);

//层序遍历 void levelOrder(Node root);

// 判断一棵树是不是完全二叉树 boolean isCompleteTree(Node root);

(Map和Set部分放到下个博客)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值