1. 数据结构
1. 链表
概念:物理存储上非连续、非顺序的存储结构;逻辑存储上通过指针链接次序实现
组成:由一系列节点通过指针链接组成,
存储方式:随机存储,见缝插针
优缺点:相对于顺序存储,插入操作更快(0(1)),无需预先分配存储空间;无法随机读取,内存消耗较大
和顺序表对比:
顺序表支持随机访问;链表不支持随机访问
顺序表插入或删除元素,效率较低(0(N));链表则只需要修改指针指向
顺序表插入数据空间不够需要扩容;链表没有容量概念
顺序表适合元素高效存储和频繁访问;链表适合频繁插入和删除;
顺序表缓存利用率高;链表缓存利用率低。(原因是因为顺序表物理空间上是连续的,增加了命中率,不用频繁从主存中读数据到缓存,提高了利用率)。
分类:单向链表,双向链表,双向循环链表,带头链表
单向链表:每个节点由数据域和指针域构成,尾部节点的指针指向null
双向链表:每个节点由两个指针域和一个数据域构成,头部节点的前指针指向Null,尾部节点的后指针指向null,节点之间的指针是双向的,既可以从头到尾遍历,也可以从尾到头遍历
单项循环链表:在单项链表的基础上,尾节点的后指针指向头节点
双向循环链表:在双向链表的基础上,尾节点的后指针指向头节点
2. 队列
队列是先进先出的线性数据结构,只能在队尾插入数据,在队头删除数据。
存储结构实现方式:顺序队列(顺序表基础上的队列),链式队列(链表基础上的队列)。两者区别仅是顺序表和链表的区别。物理空间中,数据集中存储的是顺序队列,数据分散存储的是链队列。
3. 栈
栈是后进先出的数据结构。特殊的线性表,栈底是固定的,只能在栈顶进行插入或删除。,顺序栈和链栈。分别基于数组和链表实现的栈。
4. 哈希表(hash table)
定义:通过key和一个映射函数计算出对应的值,把关键码值映射到表中一个位置来访问记录,以加快查询速度。
哈希函数:将哈希表中元素的关键值映射为元素存储位置的函数
哈希冲突:不同的关键字通过同一个哈希函数可能得到同一哈希地址
哈希函数构建常用方法:直接定址法、除留余数法、平方取中法
哈希冲突解决办法:开放地址法、链地址法
5. 树(Tree)
定义:树是n(n>=0)个节点的有限集,n=0,即为空树。
树也是一种递归的实现,树的定义中还用到树的概念。
特点:有且只有一个根节点;当节点数大于1时,其节点可以分为m个互不相交的有限集;每一个集合本身也是一棵树,统称为根的子树。
二叉树:是n个节点的有限集合(n>=0);由1个根节点和两颗互不相交的左子树和右子树组成。
线性结构&树结构:单独使用顺序存储结构(数组)无法很好的表现树的存储概念,不过可充分利用顺序存储和链式存储的特点,完全可以实现数的存储结构的表示
线性表和树的对别:线性结构第一个元素无前驱,最后一个元素无后继,中间元素一个前驱一个后继;树结构根节点无双亲且唯一,叶节点无孩子且可以多个,中间节点仅1个双亲和多个孩子。
二叉树(Binary Tree)定义:是n个节点的有限集合。该集合为空集或者由1个根节点和两棵互不相交的分别称为根节点的左子树和右子树的二叉树组成。
二叉树特点:每个节点最多只能有2棵树;左树和右树的次序不能随意颠倒;即便树种某个节点中只有一棵子树,也要区分左子树还是右子树。
二叉树五种基本形态:空二叉树,仅有一个根节点,根节点只有左子树,根节点只有右子树,根节点既有左子树又有右子树
二叉树遍历定义:从根节点出发,按照某种次序依次访问二叉树种所有节点,每个节点仅被访问1次。
二叉树的四种遍历方式:前序遍历,中序遍历, 后续遍历,层序遍历
参考资料:https://blog.csdn.net/liu17234050/article/details/104256408
前序遍历:先访问根节点,前后前序遍历左子树,最后前序遍历右子树。
总结:根节点->左子树->右子树。
中序遍历:从根节点开始(并不是先访问根节点),中序遍历根节点的左子树,然后访问根节点,最后访问右子树。
总结:左子树->根节点->右子树
后续遍历:从左到右先叶子后节点的方式遍历访问左右子树,最后访问根节点。
总结:从左到右访问叶子节点,最后访问根节点。
层次遍历:从树的第一层,即根节点开始访问,由上而下逐层遍历,在同一层中从左到右的顺序逐个节点进行访问。
总结:第二层->第二层->…最后一层(从左到右的顺序进行访问)
赫夫曼编码:构造一棵二叉树,若树的带权路径长度达到最小,则这颗树被称为哈夫曼树/赫夫曼树。
涉及定义补充
路径:在树中,从一个节点往下可以达到的孩子或孙子节点之间的道路,称为路径。
路径长度:通路中分支的树木称为路径长度。
如果根节点层数为1,则L层节点的路径长度是L-1。
节点的权:树种节点有特殊含义的值,称为该节点的权。
节点带权路径长度:节点路径长度 ✖ 节点的权。例如节点20的路径长度是3,则其带权路径长度是20✖3=60
树的带权路径长度:所有叶子节点(无子节点)的带权路径长度之和。记为WPL.
5. 图(Graph)
定义:由顶点的的有穷非空集合和顶点之间的边的集合组成。
通常表示为G(V,E).G表示图,V表示图G种顶点的集合,E表示图G种边的集合。
线性表&树&图之间的关系(数据元素名称、有无节点、内部之间的关系):
线性表种数据称为元素、树中数据称为节点、图中元素称为顶点
线性表可以没有元素,称为空表;树中可以没有节点,称为空树;图中不能没有顶点。
图的5种种类:
无向图:图中任意两个顶点之间都是无向边,无向图顶点的边树叫做度。
有向图:图中任意两个顶点之间都是有向边,有向图顶点分为入度(箭头朝向自己)和出度(箭头朝外)
简单图:在图中,若不存在顶点到自身的边,且一条边不重复出现。
完全无向图:在无向邮箱图中,如果任意两个顶点之间都存在边,则是无线完全图
有向完全图:在有向图中,如果任意两个顶点都存在方向互相相反的两条弧,则是有有向完全
6. 字符串
定义:字符串要单独使用一种独特存储结构来存储,称为串存储结构。这里的串即是字符串。
特殊的串:
空串:存储0个字符的串。String s = “”;
空格串:只包含空格字符的串。String s= “ ”; 双引号包含5个空格
子串和主串:如果字符串a有几个连续字符和b完全相同,则a是b的主串,b是a的子串。
三种存储结构:定长顺序存储(使用普通数据{静态数组}存储),堆分配存储(使用动态数组存储),块链存储(使用链表存储)
7. 单调栈
单调栈中存放数据有序,分为单调递增栈和单调递减栈。
单调递增栈:栈顶至栈底是从小到大
单调递减栈:栈顶至栈底是从大到小
单调递增站,栈底最大;单调递减栈, 栈低最小。
模拟单调递增栈:
一组数字:10,3,7,4,12,从左至右依次进行入栈,如果栈为空或入栈元素小于栈顶元素则入栈,否则强行入栈会破坏栈的单调性,需要将比入栈元素小的元素全部出栈。单调递减栈反之。
8. 字典树(TrieTree)
定义:字段树是一种树形结构,典型应用是用于统计、排序和保存大量的字符串(但不限于字符串,如01字段树)。主要思想是利用字符串的公共前缀来节约存储空间和检查查询时间,最大限度减少无谓的字符串比较,查询效率比哈希树高。
参考代码字段:https://blog.csdn.net/m0_46202073/article/details/107253959
9. 线段树
todo
10. 并查集
todo
2. 算法
2.1 排序
2.1.1 冒泡排序
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
1. 算法步骤
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
2.Java 代码实现
public class Main {
public static void main(String[] args) {
int[] arr = {13,4324,432,67,8,3,1,1};
int[] ar = sort(arr);
for(int i = 0;i< ar.length;i++){
System.out.println("ar["+i+"]="+ar[i]);
}
}
public static int[] sort(int[] sourceArray) {
for (int i = 1; i < sourceArray.length; i++) {
// 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
boolean flag = true;
for (int j = 0; j < sourceArray.length - i; j++) {
if (sourceArray[j] > sourceArray[j + 1]) {
int tmp = sourceArray[j];
sourceArray[j] = sourceArray[j + 1];
sourceArray[j + 1] = tmp;
flag = false;
}
}
if (flag) {
break;
}
}
return sourceArray;
}
}