数据结构与集合原码
文章目录
- 数据结构与集合原码
- 1. 数据结构基本概念
- 1.1 概念
- 1.2 数据结构的研究对象
- 2. 常见存储结构
- 2.1 数组
- 2.2 链表
- 2.2.1 单向链表
- 2.2.2 双向链表
- 2.3 二叉树
- 2.4 栈(stack)
- 2.5 队列
- 3. 二叉树
- 3.1 二叉树的遍历
- 3.2 经典二叉树
- 4. List实现类源码分析
- 4.1 ArrayList
- 4.2 LinkedList
- 4.3 启示
- 5. HashMap实现类源码分析
- 5.1 jdk8与jdk7中的不同
1. 数据结构基本概念
1.1 概念
- 数据结构:一种程序设计优化的方法论,研究数据的“逻辑结构” 和 “物理结构” 以及它们之间的相互关系,并对这种结构定义相应的”运算“。目的是加快程序的执行速度、减少内存占用的空间
1.2 数据结构的研究对象
- 研究对象1:逻辑结构
- 集合结构
- 线性结构:一对一
- 树形结构:一对多
- 图形结构:多对多
- 研究对象2:物理结构(存储结构)
- 顺序结构
- 链式结构
- 索引结构
- 散列结
- 研究对象3:相关算法操作
- 分配资源,建立结构,释放资源
- 插入和删除
- 获取和遍历
- 修改和排序
2. 常见存储结构
2.1 数组
- 所有数据存储在一个连续的空间中,紧密排布,不能有间隔
2.2 链表
- 链表中基本单位:节点(Noad)
2.2.1 单向链表
class Node{Object data;Node next;public Node(Object data){this.data = data;}
}//创建对象
Node node1 = new Node("AA");
Node node2 = new Node("BB");
Node node3 = new Node("CC");
node1.next = node2;
node2.next = node3;
2.2.2 双向链表
class Node{Node pre;Object data;Node next;public Node(Object data){this.data = data;}public Node(Node pre, Object data, Node next){this.pre = pre;this.data = data;this.next = next;}
}//创建对象
Node node1 = new Node(null, "AA", null);
Node node2 = new Node(node1, "BB", null);
Node node3 = new Node(node2, "CC", null);
node1.next = node2;
node2.next = node3;
2.3 二叉树
class TreeNode{TreeNode left;Object data;TreeNode right;public TreeNode(Object data){this.data = data;}public TreeNode(TreeNode left, Object data, TreeNode right){this.left = left;this.data = data;this.right = right;}
}//创建对象
TreeNode node1 = new TreeNode(null, "AA", null);
TreeNode leftNode = new TreeNode(null, "BB", null);
TreeNode rightNode = new TreeNode(null, "CC", null);
node1.left = leftNode;
node1.right = rightNode;
2.4 栈(stack)
-
先进后出
-
特点:
- 栈是抽象数据结构(ADT)
- 可以用数组或链表构建
class Stack{Object[] values;int size;public Stack(int length){values = new Object[length];}//入栈public void push(Object o){if(size >= values.length){throw new RuntimeException("栈空间已满,入栈失败");}values[size] = o;size++;}//出栈public Object pop(){if(size <= 0){throw new RuntimeException("栈空间已空,出栈失败");}Object obj = values[size-1];values[size-1] = null;size--;return obj;}
}
2.5 队列
- 先进先出
- 特点:
- 栈是抽象数据结构(ADT)
- 可以用数组或链表构建
3. 二叉树
3.1 二叉树的遍历
- 先序遍历(根,左,右):A,B,D,H,I,E,C,F,G
- 中序遍历(左,根,右):H,D,I,B,E,A,F,C,G
- 后序遍历(左,右,根):H,I,D,E,B,F,G,C,A
3.2 经典二叉树
-
二叉排序树(BST)
-
左节点的数始终小于根节点,右节点的数始终大于根节点
此时进行中序遍历,会得到有序集合
-
-
平衡二叉树(AVL) —— 满足是二叉排序树的条件下,具有以下特点
- 左右两个子树的高度差的绝对值不超过1
-
红黑树 —— 满足是二叉排序树的条件下,具有以下特点
- 每个节点是红色/黑色
- 根节点是黑色
- 每个叶子结点是黑色
- 每个红色节点的两个子节点都是黑色
- 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点
4. List实现类源码分析
4.1 ArrayList
-
jdk7.0:类似(饿汉式)
//创建对象:底层初始化数组,数组长度为10:Object[] elementData = new Object[10]; ArrayList list = new ArrayList();//当添加元素长度达到10时,会扩容为原来的1.5倍,并将原来的数组复制到新的数组中
-
jdk8.0:类似(懒汉式)
//创建对象:底层初始化数组:Object[] elementData = new Object[]{}; ArrayList list = new ArrayList();
4.2 LinkedList
- 不存在扩容问题
4.3 启示
-
ArrayList:查找和添加效率高,时间复杂度O(1)
删除和插入效率低,时间复杂度O(n)
-
LinkedList:查找和添加效率低,时间复杂度O(n)
删除和插入效率高,时间复杂度O(1)
5. HashMap实现类源码分析
5.1 jdk8与jdk7中的不同
- jdk8中,创建HashMap实例后,底层没有初始化table数组。当首次添加(key, value)时,进行判断,若发现table尚未初始化,则对数组进行初始化
- jdk8中,HashMap底层定义了Node内部类,替换jdk7中的Entry内部类。意味着,创建的数组是Node[]
- jdk8中,如果当前(key, value)经过一系列判断之后,可以添加到数组角标i中。——》如果此时 i 位置上有元素。在idk7中是将新的(key, value)指向已有的旧的元素(头插法)。而在jdk8中是旧的元素指向新的元素(尾插法)———— “七上八下”