参考视频: 【黑马程序员】2020最新数据结构与算法教程(求职面试必备)
参考leetcode学习资料: 图解算法数据结构
线性表是最基本,最简单,也是最常用的一种数据结构;一个线性表是n个具有相同特性的数据元素的有限序列
线性表的特征 : 数据元素之间具有“一对一”的逻辑关系
线性表分类 :
顺序表API设计 :
类名 | SequenceList |
---|---|
构造方法 | SequenceList(int capacity) : 创建容量为capacity的SequenceList对象 |
成员方法 | 1. public void clear() : 空置线性表 2. public boolean isEmpty() : 判断线性表是否为空, 是返回true,否则返回false 3. public int length() : 获取线性表中元素的个数 4. public T get(int i) : 获取并返回线性表中第i个元素的值 5. public void insert(int i, T t) : 在线性表中的第i个元素之前插入一个值为t的数据元素 6. public void insert(T t) : 向线性表中添加一个元素t 7. public T remove(int i):删除并返回线性表中第i个数据元素 8. public int indexOf(T t) : 返回线性表中首次出现的指定的数据元素的位序号,若不存在,则返回-1 |
成员变量 | 1. private T[] eles : 存储元素的数组 2. private int N : 当前线性表的长度 |
顺序表的遍历
顺序表的容量可变
我们使用SequenceList时, 先new SequenceList(5)创建一个对对象,创建对象就需要指定容器的大小,初始化指定大小的数组来存储元素。
这种设计不符合容器的设计理念,我们在设计顺序表时,应该考虑容器的伸缩性
O(1)
O(n)
由于顺序表的底层有数组实现, 数组的长度是固定的,所以操作时涉及了容器扩容操作(申请内存重建数组),会导致顺序表在使用过程中的时间复杂度不是线性的,在某些需要扩容的节点处,耗时会突增
顺序表的查询很快,时间复杂度为O(1),但是增删的效率很低,每次增删操作都伴随着大量数据元素移动
链表是一种物理存储单元上非连续、非顺序的存储结构,其物理结构不能只表示数据元素的逻辑结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
如何使用链表 :
结点API设计
类名 | Node |
---|---|
构造方法 | Node( T t, Node next) : 创建Node对象 |
成员变量 | T item : 存储数据 Node next : 指向下一个节点 |
结点类实现 :
public class Node<T>{ //存储元素 public T item; // 指向下一个结点 public Node next; public Node(T item, Node next){ this.item = item; this.next = next; } }
生成链表 :
public static void main(String[] args) throw Exception{ //构造结点 Node<Integer> first = new Node<Integer>(11,null); Node<Integer> second = new Node<Integer>(11,null); Node<Integer> third = new Node<Integer>(11,null); Node<Integer> fourth = new Node<Integer>(11,null); }
单向链表API设计
类名 | LinkList |
---|---|
构造方法 | LinkLsit() : 创建LinkList对象 |
成员方法 | 1. public void clear() : 空置线性表 2. public boolean isEmpty(): 判断线性表是否为空,true或false 3. public int length() : 获取线性表中元素的个数 4. public T get(int i) : 读取并返回线性表中的第i个元素的值 5. public void insert(T t) : 往线性表中添加一个元素 6. public void insert(int i.T t): 王线性表的第i个元素之前插入一个值为t的数据元素 7. public T remove(int i) : 删除并返回线性表中第i个数据元素 8. public int indexOf(T t) : 返回线性表中首次出现的指定的数据元素的位序号,若不存在,则返回-1 9. public T getFirst(): 获取第一个元素 10 public T getLast(): 获取最后一个元素 |
成员内部类 | private class Node: 结点类 |
成员变量 | 1. private Node first : 记录首结点 2. private Node last : 记录尾结点 2. private int N: 记录链表的长度 |
双向链表也叫双向表,是链表的一种,由多个结点组成,每个结点都由一个数据域和两个指针域组成,
按照面向对象的思想,需要设计一个类,来描述结点这个事物
结合API设计
类名 | Node |
---|---|
构造方法 | Node(T t,Node pre,Node next()) : 创建Node对象 |
成员变量 | T item:存储数据 Node next: 指向下一个结点 Node pre:指向上一个结点 |
双向链表API设计 :
类名 | TowWayLinkList |
---|---|
构造方法 | TowWayLink(): 创建TowWayLinkLink对象 |
成员方法 | 1. public void clear() : 空置线性表 2. public boolean isEmpty(): 判断线性表是否为空,true或false 3. public int length() : 获取线性表中元素的个数 4. public T get(int i) : 读取并返回线性表中的第i个元素的值 5. public void insert(T t) : 往线性表中添加一个元素 6. public void insert(int i.T t): 王线性表的第i个元素之前插入一个值为t的数据元素 7. public T remove(int i) : 删除并返回线性表中第i个数据元素 8. public int indexOf(T t) : 返回线性表中首次出现的指定的数据元素的位序号,若不存在,则返回-1 |
成员内部类 | private Node first : 记录首结点 |
成员变量 | 1.private Node first: 记录首结点 2.private Node last: 记录尾结点 3.private int N: 记录 |
java中的LinkList集合也是使用双向链表实现,并提供了增删改查等
底层是否用双向链表实现
节点类是否有三个域 : 两个指针域和一个数据域
get int(i)
: 每一次查询, 都需要从链表的头部开始,依次向后查找,随着数据元素N的增多,比较的元素越多,时间复杂度为O(n)insert(int i, T t):
每一次插入,需要先找到i位置的前一个元素,然后完成插入操作,随着数据元素N的增多,查找的元素越多,时间复杂度为O(n)单链表的反转,是面试中的一个高频题目
需求:
快慢指针指向有环无环问题
最后一个指针的指针域指向第一个结点
循环链表的构建:
public class FastSlowTest { public static void main(String[] args) throws Exception{ // 创建结点 Node<String> first = new Node<String>("aa", null); Node<String> second = new Node<String>("bb", null); Node<String> third = new Node<String>("cc", null); Node<String> fourth = new Node<String>("dd", null); Node<String> fifth = new Node<String>("ee", null); Node<String> six = new Node<String>("ff", null); Node<String> seven = new Node<String>("gg", null); // 完成结点之间的指向 first.next = second; second.next = third; third.next = fourth; fourth.next = fifth; fifth.next = six; six.next = seven; // 构建循环链表,让最后一个结点指向第一个结点 } }
生活中的栈 引入到计算机中, 就是提供数据休息的地方; 数据可以进入栈中,也可以从栈中出去
栈是一种基于先进后出(FILO)的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。
按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出)
我们称数据进入到栈的动作是压栈,数据从栈中出去的动作为弹栈
栈API设计
类名 | Stack |
---|---|
构造方法 | Stack: 创建Stack对象 |
成员方法 | 1. public boolean isEmpty(): 判断栈是否为空,是返回true,否返回false 2. public int size(): 获取栈中元素的个数 3. public T pop(): 弹出栈顶元素 4. public void push(T t): 向栈中压入元素t |
成员变量 | 1. private Node head: 记录首结点 2. private int N: 当前栈的元素个数 |
成员内部类 | private class Node: 节点类 |
给定一个字符串,里边包含"()"小括号和其他字符,请编写检查该字符串的小括号是否成对出现
例如: "(上海)(长安)": 是否匹配 "上海((长安))": 正确匹配 “上海(长安(北京)(深圳)南京)”: 正确匹配 “上海(长安))”: 错误匹配 “((上海)长安”: 错误匹配
示例代码:
队列是一种基于先进先出(FIFO)的数据结构,是一种只能在一端进行插入,在另一端进行删除操作的特殊线性表,它代表先进先出的原则存储数据,先进入的数据,在读取数据时先读被读出来
1.
类名 | Queue |
---|---|
构造方法 | Queue():创建Queue对象 |
成员方法 | 1. public boolean isEmpty(): 判断队列是否为空,是返回true,否返回 false 2. public int size(): 获取队列中元素的个数 3. public T dequeue(): 从队列中拿出一个元素 4. publilc void enqueue(T t): 往队列中 插入 一个元素 |
成员变量 | 1. private Node head: 记录首结点 2. private int N: 当前栈的元素个数 3. private Node last: 记录最后一个结点 |
成员内部类 | private class Node: 节点类 |
符号表最主要的目的就是将一个键和一个值联系起来,符号表能够存储的数据元素是一个键和一个值共同组成的键值对数据,可以根据键来查找对应的值
符号表在实际生活中的使用场景很广泛
应用 | 查找目的 | 键 | 值 |
---|---|---|---|
字典 | 找到单词的释义 | 单词 | 释义 |
图书索引 | 找到某个术语相关的页码 | 术语 | 一串页码 |
网络搜索 | 找到某个关键字对应的网页 | 关键字 | 网页名称 |
符号表API设计
类名 | Node<key.Value> |
---|---|
构造方法 | Node(Key key,Value value,Node next):创建Node对象 |
成员变量 | 1. public Key key: 存储键 2. public Value value:存储值 3. public Node next:存储下一个结点 |
符号表:
类名 | SymbolTable<Key.Value> |
---|---|
构造方法 | SYmbolTable():创建SymbolTable对象 |
成员方法 | 1. public Value get(Key key):根据键key,找对应的值 2. public void put(Key key , Value val):想符号表中插入一个键值对 3. public void delete(Key key):删除键为key的键值对 4. public int size(): 获取符号表的大小 |
成员变量 | 1. private Node head: 记录首结点 2. private int N: 记录符号表中键值对的个数 |
orderSymbolTable.java
线性结构:底层的的结构可以是数组(查询快),也可以是线性表(增增删慢)
每日小知识:为啥子我直接粘贴笔记,不会显示“图片外链无法获取”,因为我的typora搭有图床:
- 参考博客:Gitee搭建免费博客
- 老方便了,随后搭个博客平台或者把文件发给别人,都不用发愁自己的图片发不出去了
笔记在博主本人的博客上也有奥!全套!!!
- 翼遥bingo【持续完善中,biu~~】