#1024程序员节 | 征文#
线性结构
最基本、最简单、最常用的一种数据结构------线性表。线性表分为一般线性表和受限线性表。
一般线性表:通常所说的线性表,可以自由地删除或添加节点。
受限线性表:节点操作受限制的线性表,如栈和队列。
线性表是n个数据元素的有限序列。线性表中的数据元素要求具有相同类型。
线性表特征:
1.有且仅有一个开始节点(表头节点),它没有直接前驱,只有一个直接后继。
2.有且仅有一个终端节点(表尾节点),它没有直接后继,只有一个直接前驱。
3.其他节点都有一个直接前驱和直接后继。
4.元素之间为一对一的线性关系。
- 数据类型:数据类型是指在编程语言中定义的一种数据的分类,指定数据的大小、取值范围、所允许的操作等。常见的数据类型包括整型、浮点型、字符型、布尔型等。
- 抽象数据类型(ADT):抽象数据类型是对数据及其操作的一种抽象描述,它定义了一组数据和对这些数据的操作,但不关心具体的实现细节。ADT强调"是什么"而非"怎么做",例如栈、队列、图等。
示例:
- 数据类型 :例如,
int
、float
、char
等。- 抽象数据类型:例如,栈(Stack)可以定义两种基本操作:入栈(push)和出栈(pop),而不关心其内部是如何用数组、链表等结构实现的。
顺序表/数组
顺序表是指用一组**++地址连续++** 的存储单元依次存储数据元素的线性表。数组 是计算机根据事先定义好的数组类型与长度自动为其分配的一组**++连续的存储单元++**,相同数组的位置和距离都是固定的,任何一个数组元素的地址都可用简单公式计算。因此这种结构可以有效地对数组元素进行随机访问。
表的简单数组实现:对表的所有操作都可以通过数组实现。虽然数组可以动态指定,但是还是需要对表大小进行估计。查找容易(索引),然而插入和删除需要的运行时间多得多,因为增删位置后面的数据都要向前或向后移动。
ArrayList的实现:ArrayList是一种++线性数据结构,底层用数组实现的++ ,与简单数组实现方式不同,它的**++容量能动态增长++**。
ArrayList特点:
链表
顺序表进行数组元素插入删除时,会引起大量数据移动,复杂低效。链表应运而生。
链表是一种++物理存储单元非连续,非顺序++ 的++存储结构++ ,数据元素的逻辑顺序是通过链表中的**++指针链接++**次序实现的。
链表由一系列节点 (链表中的每一个元素称为一个节点)组成,节点可以在运行时动态生成。每个节点包括两部分:++存储数据元素的数据域 ,指向下一个指针的指针域++。指针域记录了下一个节点的地址。
使用链表克服了顺序表要预先知道数据大小的缺点。链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。插入删除方便,元素无需大量移动; 查找不方便。
Java没有显式的使用指针
单向链表
大佬文章 Java实现单链表(步骤详解+源码)_java单链表-CSDN博客
单向链表的节点结构
java
public class Node {
private T data;
private Main.Node next=null;
private Node (T data){
this.data=data;
}
//获得某节点下一个节点
public Main.Node getNext(){
return next;
}
//获得某节点存储的数据
public T getData(){
return data;
}
}
链表的删除
寻找特定节点的前驱节点
链表的插入
测试链表是否为空表
当前链表是否为最后一个节点
查找指定元素的节点,返回找到的第一个节点,未找到返回null
获取链表下一个节点
++上面的回来再补++
双向链表
双向链表在单向链表数据结构上附加了一个域,使它包含指向前一个节点的指针。它的开销增加了一个附加的链,增加了对空间的需求,同时也使插入和删除的运行时间增加了一倍。在**++插入删除++** 时的操作和原来的单链表有不同,这次需要**++修改两个方向上的指针++**。
JDK对双向链表节点的定义
java
private static class Node<E>{
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next){
this.item=element;
this.next=next;
this.prev=prev;
}
}
删除节点
插入节点
++回头写++
循环链表
让最后一个节点反过来指向第一个节点,整个链表形成一个环。
链表应用:例如实现一元多项式及其运算
哈希表
查找方法
顺序表的查找
- 从顺序表的第一个元素开始,逐个与要查找的关键字比较。
- 如果找到与关键字相等的元素,则返回该元素在顺序表中的位置。
- 如果遍历完整个顺序表都没有找到与关键字相等的元素,则返回一个表示未找到的标志,通常为0或-1。
java
int Search_Sequen(SSTable ST, KeyType key) {
// 在线性表 ST 中顺序检索其关键字等于Key的数据元素,
// 若找到,函数值为该元素在表中的位置,否则为 -1.
ST.element[ST.length].key=key; //设置监视哨
i=0;
while (ST.element[i].key != key) i++;
if (i < ST.length)
return i;
else
return -1;
}
有序表的查找
折半查找
java
int BinarySearch(int a[],int x,int n){
int left = 0;
int right = n-1;
while(left <= right){
int mid=(left+right)/2;
if(x==a[middle])
return middle;
if(x>a[middle])
left=middle+1;
else
right=middle-1;
}
return -1;
}
索引顺序表的查找
又叫++分块查找++
分块查找,又称索引顺序查找,是顺序查找法与二分法的一种结合。其基本思想是将线性表分成若干块,每一块中的结点存放不必有序,但块与块之间必须有序。
- 、查找过程 :
- 首先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中。
- 然后在已确定的块中用顺序法进行查找。
散列表的查找
散列,又称哈希,是一种重要的存储方法,也是一种常见的查找方法。
基本思想:以元素的关键字key为自变量,通过一个确定的函数关系h,计算出对应的函数值h(key),把这个值解释为元素的存储地址,并按此存放;查找时,由同一个函数对给定值kx计算地址,将kx与地址单元中元素关键字进行比较,确定查找是否成功。因此散列法又称为关键字-地址转换法 。其中转换函数称为++散列函数++ ,这个思想构造的表称为++散列表++。
当两个关键字散列到同一个值,称为冲突。
常见散列函数
1.直接定址法:简单但适用范围有限
2.数字分析法:选取关键码中分布均匀的几位作为散列地址。这种方法适用于关键码的某些位上符号分布均匀的情况。
3.平方取中法:通过取关键字的平方值的中间若干位作为散列值。这种方法较少使用,因为其计算复杂度较高。
4.折叠法:当关键码位数较多时,将关键码分割成若干部分,然后将这些部分叠加起来形成散列地址。
5.除留余数法:将关键字除以一个数取余数作为散列值,例如H(key) = key % mod。这种方法适用于关键字分布均匀的情况,特别是当mod为素数时。
如何解决冲突
拉链法
开放定址法
不建立链表,仍设散列表的长度为M,地址范围为[0,M-1]。从空表开始,通过逐个向表中插入新元素来建立散列表。
插入关键字值为key的新元素的方法 是:从h(key)开始,按照某种规定的次序探查允许插入新元素的空位置。地址h(key)为基位置。如果h(key)已经被占用了,那么就需要有一种解决冲突的策略来确定如何探查下一个空位置。所以这种方法也称为++空缺编址法++。
根据生成探查序列的规则不同,有++线性探查法、伪随机探查法、平方探查法和双散列探查法++等开发定址法。
再散列法
++装填因子α=填入表中的元素个数/散列表的长度++
所以α越大,填入表的元素越多,产生冲入的可能性越大。
队列
限定在表的一端插入,在表的另一端删除的线性表。
FIFO:先进先出。
队列ADT
add:向队列中加入一个新元素
remove:从队列首部移除一个元素
peek:返回队首元素,而不将其移除
队列的顺序/数组实现
假溢出👇
可能出现++假溢出++ ,改进方法:++循环队列++。
循环队列
队头指针进1:head=(head+1)%MaxQueueSize
队尾指针进1:tail=(tail+1)%MaxQueueSize
在循环队列结构下,当head=tail为空队列;当(tail+1)%MaxQueueSize=head为满队列。
例👇
队列的链接表示
head和tail分别指向队头和队尾节点。
栈
限定插入和删除都在同一端进行的线性表。
LIFO:后进先出。
栈ADT
Stack:建栈
push:入栈
pop:出栈
peek:返回栈顶元素
empty:判断是否是空栈
search:查找元素在栈的位置
栈有++顺序和链接++两种表达方式。
大佬文章 数据结构------栈_栈分为哪两种-CSDN博客
栈的顺序表示
顺序栈的函数实现
++回头写++
栈的链接表示
栈顶指针指向栈顶元素
链式栈的函数实现
++回头写++
常见应用场景:表达式计算
计算后缀表达式的值
中缀表达式转换为后缀表达式
利用两个栈计算表达式
递归和栈的关系
矩阵(百度说是线性结构)
稀疏矩阵:数值为0的元素数目远多于非零元素数目
稠密矩阵:非零元素数目多
特殊矩阵:上三角/下三角/对角矩阵
对称矩阵关于主对角线对称,只需存储上/下三角即可。
三角矩阵:下图c为一个常数
带状矩阵:
大佬文章 数组与矩阵-CSDN博客
矩阵的压缩存储 :大佬文章 矩阵的压缩存储-CSDN博客
三元组表示 :大佬文章稀疏矩阵的三元组表表示法及其转置_三元组稀疏矩阵转置-CSDN博客
十字链表 :大佬文章稀疏矩阵的链式存储结构:十字链表-CSDN博客
排序
冒泡、选择、插入、希尔
非线性结构
堆(优先队列)
树
树基础知识
树的实现
java
public class MyTree1 {
class TreeNode {
Object value;
TreeNode firstChild;//第一个儿子节点
TreeNode nextSibling;//第一个兄弟节点
}
//根节点
TreeNode root;
//树节点数目
int size=0;
}