![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
文章平均质量分 73
数据结构与算法课程实验与学习总结
长齐克斯
Java待就业
展开
-
跳表JAVA实现
1.跳表的定义跳跃表是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间),并且对并发算法友好。SkipList(跳表)是一种可以代替平衡树的数据结构,默认是按照Key值升序的。SkipList让已排序的数据分布在多层链表中,以0-1随机数决定一个数据的向上攀升与否,通过“空间来换取时间”的一个算法,在每个节点中增加了向前的指针,在插入、删除、查找时可以忽略一些不可能涉及到的结点,从而提高了效率。在Java的API中已经有了实现:分别是:Conc原创 2021-05-21 19:58:14 · 874 阅读 · 3 评论 -
图的深度优先搜索与广度优先搜索(JAVA)
图的存储结构一、邻接矩阵 (Adjacency Matrix)表示(数组表示法)基本思想:用一个一维数组存储图中顶点的信息,用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。假设图G=(V,E)有n个顶点,则邻接矩阵是一个n×n的方阵,定义为:无向图的邻接矩阵:存储结构特点:主对角线为 0 且一定是对称矩阵;有向图的邻接矩阵:假设图G有n个顶点e条边,则该图的存储需求为O(n+n^2) = O(n^2) ,与边的条数e无关。存储结构的建立----算法实现的步骤:确定图原创 2021-02-09 23:55:12 · 12134 阅读 · 1 评论 -
AVL树
AVL树的性质AVL树(Balanced Binary Tree or Height-Balanced Tree)AVL树或者是空二叉树,或者是具有如下性质的BST:根结点的左、右子树高度之差的绝对值不超过1且根结点左子树和右子树仍然是AVL树。结点的平衡因子BF(Balanced Factor)一个结点的左子树与右子树的高度之差。AVL树中的任意结点的BF只可能是-1,0和1。AVL树的ASL可保持在O(log2n)在AVL树在结点高度上采用相对平衡的策略,使其平均性能接近于B原创 2021-02-09 00:27:38 · 19039 阅读 · 1 评论 -
二叉排序树(BST)
BST结构特点任意一个结点的关键字,都大于(小于)其左(右)子树中任意结点的关键字,因此各结点的关键字互不相同按中序遍历二叉查找树所得的中序序列是一个递增的有序序列,因此,二叉查找树可以把无序序列变为有序序列。同一个数据集合,可按关键字表示成不同的二叉查找树,即同一数据集合的二叉查找树不唯一;但中序序列相同。若它的左子树不空,则左子树上所有结点的关键字的值都小于根结点关键字的值;若它的右子树不空,则右子树上所有结点的关键字的值都大于根结点关键字的值;它的左、右子树本身又是一个二叉查找树。原创 2021-02-08 12:51:24 · 12910 阅读 · 1 评论 -
哈夫曼树与哈夫曼编码(java实现)
二叉树的带权路径长度:设二叉树具有n个带权值的叶子结点,从根结点到各个叶子结点的路径长度与相应叶子结点权值的乘积之和。 记为:举例:给定4个叶子结点,其权值分别为{2,3,4,7},可以构造出形状不同的二叉树哈夫曼树: 给定一组具有确定权值的叶子结点,带权路径长度最小的二叉树,称为哈夫曼树,亦称最优二叉树。哈夫曼树的特点:权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点。(构造哈夫曼树的核心思想)只有度为0(叶子结点)和度为2(分支结点)的结点,不存在度为1的结点。n个原创 2021-02-04 00:17:20 · 1704 阅读 · 2 评论 -
线索二叉树
二叉树的线索链表存储结构二叉链表的空间利用情况:在n(n≥1)个结点的二叉树左右链表示中,只有n-1个指向子树的指针,却有n+1个空指针域。如何利用空指针域解决上述问题?若结点p有左孩子,则p->lchild指向其左孩子结点,否则令其指向其(先序、中序、后序、层序)前驱;若结点p有右孩子,则p->rchild指向其右孩子结点,否则令其指向其(先序、中序、后序、层序)后继;如何区分指针是指向其左/右孩子的指针还是指向某种遍历的前驱/后继?在每个结点中增加两个标志位,以区分该结点的原创 2021-02-03 16:25:18 · 635 阅读 · 0 评论 -
二叉树的顺序存储结构
完全二叉树的顺序存储结构的性质:若i = 1, 则 i 是根结点,无父结点;若i > 1, 则 i 的父结点为 i/2 ,向下取整若 2i <= n, 则 i 有左儿子且为 2i;否则,i 无左儿子。若 2i+1 <= n, 则 i 有右儿子且为2i+1;否则,i 无右儿子若 i 为偶数, 且 i < n , 则有右兄弟,且为 i + 1。若 i 为奇数, 且 i < n && i != 1, 则其左兄弟,且为 i-1完全二叉树的顺序存储结构原创 2021-02-03 14:24:03 · 6060 阅读 · 0 评论 -
二叉树的前序中序和后序遍历
遍历的定义根据某种策略,按照一定的次序访问二叉树中的每一个结点,使每个结点被访问一次且只被访问一次。这个过程称为二叉树的遍历。遍历的结果是二叉树结点的线性序列。非线性结构线性化。策略:左孩子结点一定要在右孩子结点之前访问先序(根)遍历二叉树若二叉树为空,则返回;否则,①访问根结点;②先序遍历根结点的左子树;③先序遍历根结点的右子树;所得到的线性序列分别称为先序(根)序列。先序遍历序列为:A B D G C E F中序(根)遍历二叉树若二叉树为空,则返回;否则,①中序遍历根结原创 2021-02-03 13:26:03 · 368 阅读 · 0 评论 -
散列技术
散列技术的基本思想把记录(元素)的存储位置和该记录的关键字的值之间建立一种映射关系。关键字的值在这种映射关系下的像,就是相应记录在表中的存储位置。散列技术在理想情况下,无需任何比较就可以找到待查的关键字,其查找的期望时间为O(1)。散列技术的相关概念散列函数:设 U 表示所有可能出现的关键字集合,K表示实际出现(实际存储)的关键字集合,即K 属于U,F[B – 1]是一个数组,其中B =O( | K| )。则,从 U 到表F[ B – 1]下标集合上的一个映射 h:U->{ 0, 1, 2,原创 2021-01-30 16:46:00 · 1613 阅读 · 0 评论 -
常见查找算法
二分查找二分查找:请对一个有序数组进行二分查找 {1,8, 10, 89, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。二分查找的思路分析首先确定该数组的中间的下标mid = (left + right) / 2然后让需要查找的数 findVal 和 arr[mid] 比较2.1 findVal > arr[mid] , 说明你要查找的数在mid 的右边, 因此需要递归的向右查找2.2 findVal < arr[m原创 2021-01-29 16:36:23 · 245 阅读 · 0 评论 -
八大排序算法
冒泡排序基本思想冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。显然,处理1遍之后,“最轻”的记录就浮到了最高位置;处理2遍之后,“次轻”的记录就浮到了次高位置。在作第二遍处理时,由于最高位置上的记录已是“最轻”的,所以不必检查。一般地,第i遍处理时,不必检查第i高位置以上的记录的关键字,因为经过前面i-1遍的处理,它们已正确地排好序。平均情原创 2021-01-26 14:53:37 · 329 阅读 · 0 评论 -
递归求解八皇后问题
递归需要遵守的重要规则执行一个方法时,就创建一个新的受保护的独立空间(栈空间)方法的局部变量是独立的,不会相互影响, 比如n变量如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了:)当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。八皇后问题介绍八皇后问题,是一个古老而著名的问题,是回溯算法的典原创 2021-01-25 15:32:25 · 114 阅读 · 0 评论 -
中缀表达式转后缀并求解计算
中缀表达式转换为后缀表达式具体步骤如下:初始化两个栈:运算符栈s1和储存中间结果的栈s2;从左至右扫描中缀表达式;遇到操作数时,将其压s2;遇到运算符时,比较其与s1栈顶运算符的优先级:4.1 如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;4.2否则,若优先级比栈顶运算符的高,也将运算符压入s1;4.3否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中新的栈顶运算符相比较;遇到括号时:5.1 如果是左括号“(”,则直接压入s15.2如果是右括号“原创 2021-01-24 15:12:23 · 442 阅读 · 1 评论 -
使用栈完成算术表达式的计算
实现思路需要两个栈来分别存储我们的操作符和数字通过一个 index 值(索引),来遍历我们的表达式如果我们发现是一个数字, 就直接入数栈如果发现扫描到是一个符号, 就分如下情况3.1 如果发现当前的符号栈为 空,就直接入栈3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符, 就需要从数栈中pop出两个数,在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈, 如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈.原创 2021-01-24 13:23:04 · 955 阅读 · 0 评论 -
栈的原理与实现(数组模拟与链表模拟)
栈的定义栈的英文为(stack)栈是一个先入后出(FILO-First In Last Out)的有序列表。栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除栈的特性:后进先出栈的应用场景:子程序的调用:在跳往子程序前,会先原创 2021-01-24 01:22:47 · 103 阅读 · 0 评论 -
单向循环链表与约瑟夫问题求解
单向环形链表将单链表中中断结点的指针端有空指针改为指向头结点,就使整个单链表形成一个环,这种头尾详解的单链表称为单循环链表,简称循环链表;示意图:注意: ①循环链表中没有NULL指针。涉及遍历操作时,其终止条件就不再是像非循环链表那样判别p或p->next是否为空,而是判别它们是否等于某一指定指针,如头指针或尾指针等。 ②在单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前的其它结点。而在单循环链表中,从任一结点出发都可访问到表中所有结点,这一优点使某些运算原创 2021-01-23 17:59:24 · 206 阅读 · 0 评论 -
双向链表的实现与常见操作
双向链表:在单链表的各结点中再设置一个指向其前驱结点的指针域示例:结点结构:优点:双向链表的主要优点是对于任意给的结点,都可以很轻易的获取其前结点和后结点实现双向查找(单链表不易做到)表中的位置i 可以用指示含有第i 个结点的指针表示。缺点:空间开销大,每个结点需要保存next和prev两个属性,因此需要更多的空间开销,同时结点的插入与删除操作也将更加耗时,因为需要操作更多的指向操作。插入操作图解:删除操作图解:代码实现:定义一个双向链表结构如下:/ 定义HeroNode原创 2021-01-23 12:45:17 · 483 阅读 · 0 评论 -
单向链表的实现与常见操作
单链表的定义:一个线性表由若干个结点组成,每个结 点均含有两个域:存放元素的信息域和存放其后继结点的指针域,这样就形成一个单向链接式存储结构,简称单向链表或单链表。(a1, a2 ,a3, a4)的存储示意图:存储结构特点:逻辑次序和物理次序不一定相同;元素之间的逻辑关系用指针表示;需要额外空间存储元素之间的关系非随机访问存取结构(顺序访问)逻辑结构示意图:先定义一个测试链表结构如下:英雄节点:class HeroNode { public int no; pu原创 2021-01-23 10:57:15 · 378 阅读 · 0 评论 -
数组实现循环队列
循环队列在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。可以解决假溢出问题。从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。除了一些简单应用之外,真正实用的队列是循环队列。顺序队列的假溢出:当元素被插原创 2021-01-22 22:18:30 · 2563 阅读 · 0 评论 -
稀疏矩阵原理与矩阵压缩
稀疏矩阵在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。矩阵压缩由于稀疏矩阵中非零元素较少,零元素较多,因此可以采用只存储非零元素的方法来进行压缩存储。由于非零元素分布没有任何规律,所以在进行压缩存储的时侯需要存储非零元素值的同时还要存储非零元素在原创 2021-01-22 20:12:33 · 2569 阅读 · 0 评论