数据结构与算法
文章平均质量分 88
程序=算法+数据结构
别团等shy哥发育
硕士在读,对分布式、中间件、容器、微服务、深度学习、机器学习与数据挖掘方面感兴趣,希望可以在这些方面和大家交流学习方法。
后续文章会搬到这里:www.codeleader.top
展开
-
线段树入门
基于arr数组构建线段树,我们根节点存储的是区间[0-5]的和,再往下面分叉,左边表示[0-2]的和,右边表示[3-5]的和,以此类推,最后所有的叶子节点就是数组中的所有数字。线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。我们判断要修改的点是位于线段树的左子树还是右子树,若是左子树,递归左子树,修改对应节点的值,若是右子树那就递归右子树,修改对应节点的值。:我们使用一个数组保存,先标记上各个节点的下标,根节点下标为0,根节点的左孩子下表为。原创 2023-04-29 00:06:24 · 1692 阅读 · 0 评论 -
Bellman-Ford算法--解决负权边问题
前阵子备考蓝桥杯的时候碰到了这个算法,感觉还挺有意思的,实现起来也非常简单。贝尔曼-福特算法(Bellman-Ford)是由理查德·贝尔曼(Richard Bellman) 和 莱斯特·福特 创立的,求解单源最短路径问题的一种算法。有时候这种算法也被称为 Moore-Bellman-Ford 算法,因为 Edward F. Moore 也为这个算法的发展做出了贡献。它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。其优于迪科斯彻算法。原创 2023-04-14 23:00:27 · 1774 阅读 · 1 评论 -
Dijkstra-单源最短路径算法
Dijkstra算法用来计算一个点到其他所有点的最短路径的算法,是一种单源最短路径算法。也就是说,只能计算起点只有一个的情况。算法的时间复杂度是On3O(n^3)On3,它不能处理存在负边权的情况。算法描述:设起点为s,dis[v]表示从s到v的最短路径长度disv∞v≠s;i原创 2023-03-14 20:52:35 · 1656 阅读 · 0 评论 -
跳跃-动态规划问题
例如,如果当前小蓝在第 3 行第 5 列,他下一步可以走到第 3 行第 6 列、第 3 行第 7 列、第 3 行第 8 列、第 4 行第 5 列、第 4 行第 6 列、第 4 行第 7 列、第 5 行第 5 列、第 55 行第 6 列、第 6 行第 5 列之一。在图中,有的位置有奖励,走上去即可获得,有的位置有惩罚,走上去就要接受惩罚。那我们可以由此建立一个搜索的坐标数组,每次从当前位置搜的时候我们就扩展坐标即可。开始时,小蓝站在方格图的左上角,即第 11 行第 11 列。输出一个整数,表示最大权值和。原创 2023-03-21 23:03:17 · 775 阅读 · 0 评论 -
简单0-1背包问题求解
这里f(0,w)表示不拿物品,价值肯定为0,f(k,0)表示被包装量为0,肯定装不下,所以第一行和第一列都是0,这里算几个关键的。我们有4件物品,背包容量为8,我们的目标是求在背包容量为8的前提下能装物品的最大价值。小明想知道再购买的物品总体积不超过V的情况下所能获得的最大价值为多少,请你帮他算算。输入第1行包含两个正整数N,V,表示商场物品的数量和小明的背包容量。,因为没拿第4件,所以背包容量没变,也不用再加第4件物品的价值。为:当背包容量为w,现在有k件物品可以偷,所能偷到的最大价值。原创 2023-03-15 00:04:08 · 539 阅读 · 0 评论 -
Floyd算法求解最短路径
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德。核心思路:通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。算法过程:从任意一条单边路径开始。左右两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。对于每一对顶点u和v,看是否存在一个顶点w使得从u到w再到v比已知的路径更短,如果更短,则更新它。上述概念来源于百度百科。原创 2023-03-13 21:49:48 · 12104 阅读 · 13 评论 -
DFS深度优先搜索解决迷宫问题
上一篇博客讲解了BFS广度优先搜索求解迷宫问题,今天试试DFS深度优先搜索。原创 2023-03-13 13:37:11 · 1018 阅读 · 0 评论 -
BFS广度优先搜索解决迷宫问题
然后不断地从队列中取出队首节点,然后再扩展它的邻居节点,再将它的邻居节点入队列(需要做一些条件判断)。我们的基本思想是按照BFS的基本操作,将迷宫看成一个无向图,每一个格子为一个节点,如果两个格子相邻且都是道路,则这两个格子之间有一条边。我们每从队列中取出一个节点的时候,将它的所有扩展结点(不包括墙和被访问过的)加入队列,同时更新这些扩展节点的。G的每个格子要么是道路,要么是障碍物(道路用1表示,障碍物用2表示)。迷宫示意图如下所示:图中start为起点,end为终点,方格中的2为障碍物。原创 2023-03-12 22:39:31 · 809 阅读 · 0 评论 -
并查集(Union-find Sets)
并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是朋友。我们对两个节点执行合并操作,输入为i和j,我们先找到i的祖先,再找到j的祖先,然后让i的祖先指向j的祖先(i和j的顺序换下也可以)。的祖先直接返回,这里有两种,一种是未进行路径压缩的版本,这种容易超时,我们一般使用的都是经过路径压缩的代码。此概念来源于百度百科。原创 2023-03-12 16:38:56 · 566 阅读 · 0 评论 -
黄金分割法(一维搜索算法)
一维搜索算法之黄金分割法1、概述2、黄金分割法3、修改后的黄金分割算法4、编程实现修改后的黄金分割算法1、概述 黄金分割法是一种区间收缩方法。 所谓区间收缩方法,指的是将含有最优解的区间逐步缩小,直至区间长度为零的方法。比如,为求函数f(x)在区间[a,b]上的最小值点,可在该区间中任取两点x1、x2x_1、x_2x1、x2,通过比较函数f(x)在这两点的函数值或者导数值等,来决定去掉一部分区间[a,x1x_1x1]或者[x2x_2x2,b],从而使搜索区间长度变小,如此迭代,直至区间收缩原创 2022-03-14 23:41:34 · 13405 阅读 · 9 评论 -
矩阵乘法的java实现
文章目录1、算法思想2、代码实现1、算法思想最近老是碰到迭代问题,小数太多手算又算不过来,写个矩阵乘法辅助一下吧。有两个矩阵A和B,计算矩阵A与B相乘之后的结果C。A的列数必须等于B的行数用矩阵A的第i行的值分别乘以矩阵B的第J列,然后将结果相加,就得到C[i][j]。矩阵A的行等于C的行,矩阵B的列等于C的列,这两个数值用来控制循环的次数,但是每一步中需要把行和列中对应的乘机求和,所以再加一个内循环控制乘法求和就行。下面我们进行矩阵乘法的测试A=[123456789111]B=[1原创 2021-10-11 21:36:41 · 1746 阅读 · 0 评论 -
LeetCode3--无重复前缀的最长子串(java实现)
一、问题引入:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例 1:输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。示例 2:输入: "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。示例 3:输入: "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序原创 2020-06-15 11:58:59 · 411 阅读 · 0 评论 -
LeetCode2--两数相加
LeetCode2–两数相加一、问题描述:给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字0之外,这两个数字不会以0开头。示例:输入:(2->4->3)+(5>6>4)输出:7—->0->8原因:342+465=807二、代码实现: public static ListNode addTwoNu原创 2020-06-14 11:19:16 · 352 阅读 · 0 评论 -
LeetCode1--两数之和
一、问题描述:给定一个整数数组nums和一个目标值target,请你在该数组中找出为目标值的那两个证书,并返回他们的数组下标。你假设每种输入只会对应一个答案。但是数组中同一个元素不能使用两遍。示例:给定 nums=[2,7,11,15],target=9因为nums[0]+nums[1]=2+7=9所以返回[0,1]二、传统的暴力查找: public int[] addnumber(int[] nums,int target){//传统的暴力查找 for(int i=原创 2020-06-13 21:56:14 · 273 阅读 · 0 评论 -
6-12 二叉搜索树的操作集 (30分)
本题要求实现给定二叉搜索树的5种常用操作。函数接口定义:BinTree Insert( BinTree BST, ElementType X );BinTree Delete( BinTree BST, ElementType X );Position Find( BinTree BST, ElementType X );Position FindMin( BinTree BST );Position FindMax( BinTree BST );其中BinTree结构定义如下:type原创 2020-07-17 12:01:07 · 189 阅读 · 0 评论 -
6-11 先序输出叶结点 (15分)
本题要求按照先序遍历的顺序输出给定二叉树的叶结点。函数接口定义:void PreorderPrintLeaves( BinTree BT );其中BinTree结构定义如下:typedef struct TNode *Position;typedef Position BinTree;struct TNode{ ElementType Data; BinTree Left; BinTree Right;};函数PreorderPrintLeaves应按照先序遍原创 2020-07-17 11:57:10 · 202 阅读 · 0 评论 -
6-10 二分查找 (20分)
本题要求实现二分查找算法。函数接口定义:Position BinarySearch( List L, ElementType X );其中List结构定义如下:typedef int Position;typedef struct LNode *List;struct LNode { ElementType Data[MAXSIZE]; Position Last; /* 保存线性表中最后一个元素的位置 */};L是用户传入的一个线性表,其中ElementType元素原创 2020-07-16 11:17:22 · 181 阅读 · 0 评论 -
6-9 二叉树的遍历 (25分)
本题要求给定二叉树的4种遍历。函数接口定义:void InorderTraversal( BinTree BT );void PreorderTraversal( BinTree BT );void PostorderTraversal( BinTree BT );void LevelorderTraversal( BinTree BT );其中BinTree结构定义如下:typedef struct TNode *Position;typedef Position BinTree;st原创 2020-07-16 11:13:57 · 207 阅读 · 0 评论 -
6-8 求二叉树高度 (20分)
本题要求给定二叉树的高度。函数接口定义:int GetHeight( BinTree BT );其中BinTree结构定义如下:typedef struct TNode *Position;typedef Position BinTree;struct TNode{ ElementType Data; BinTree Left; BinTree Right;};要求函数返回给定二叉树BT的高度值。裁判测试程序样例:#include <stdio.h&原创 2020-07-15 11:03:57 · 204 阅读 · 0 评论 -
6-7 在一个数组中实现两个堆栈 (20分)
本题要求在一个数组中实现两个堆栈。函数接口定义:Stack CreateStack( int MaxSize );bool Push( Stack S, ElementType X, int Tag );ElementType Pop( Stack S, int Tag );其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:typedef int Position;struct SNode { ElementType *Data; Pos原创 2020-07-15 11:01:26 · 171 阅读 · 0 评论 -
6-6 带头结点的链式表操作集 (20分)
本题要求实现带头结点的链式表操作集。函数接口定义:List MakeEmpty(); Position Find( List L, ElementType X );bool Insert( List L, ElementType X, Position P );bool Delete( List L, Position P );其中List结构定义如下:typedef struct LNode *PtrToLNode;struct LNode { ElementType Data原创 2020-07-14 11:31:18 · 266 阅读 · 0 评论 -
6-5 链式表操作集 (20分)
本题要求实现链式表的操作集。函数接口定义:Position Find( List L, ElementType X );List Insert( List L, ElementType X, Position P );List Delete( List L, Position P );其中List结构定义如下:typedef struct LNode *PtrToLNode;struct LNode { ElementType Data; PtrToLNode Next;原创 2020-07-14 11:27:53 · 246 阅读 · 1 评论 -
6-4 链式表的按序号查找 (10分)
本题要求实现一个函数,找到并返回链式表的第K个元素。函数接口定义:ElementType FindKth( List L, int K );其中List结构定义如下:typedef struct LNode *PtrToLNode;struct LNode { ElementType Data; PtrToLNode Next;};typedef PtrToLNode List;L是给定单链表,函数FindKth要返回链式表的第K个元素。如果该元素不存在,则返回ERR原创 2020-07-13 19:37:13 · 167 阅读 · 0 评论 -
6-3 求链式表的表长 (10分)
函数接口定义:int Length( List L );其中List结构定义如下:typedef struct LNode *PtrToLNode;struct LNode { ElementType Data; PtrToLNode Next;};typedef PtrToLNode List;L是给定单链表,函数Length要返回链式表的长度。裁判测试程序样例:#include <stdio.h>#include <stdlib.h>t原创 2020-07-13 19:34:47 · 209 阅读 · 0 评论 -
6-2 多项式求值 (15分)
本题要求实现一个函数,计算阶数为n,系数为a[0] … a[n]的多项式f(x)=∑i=0n(a[i]×xi) 在x点的值。函数接口定义:double f( int n, double a[], double x );其中n是多项式的阶数,a[]中存储系数,x是给定点。函数须返回多项式f(x)的值。裁判测试程序样例:#include <stdio.h>#define MAXN 10double f( int n, double a[], double x );原创 2020-07-12 23:35:37 · 261 阅读 · 0 评论 -
6-1 单链表逆转 (20分)
本题要求实现一个函数,将给定的单链表逆转。函数接口定义:List Reverse( List L );其中List结构定义如下:typedef struct Node *PtrToNode;struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */};typedef PtrToNode List; /* 定义单链表类型 */L是给定单链表,函数Reverse要返回被逆转原创 2020-07-12 23:32:19 · 421 阅读 · 0 评论 -
输出二叉树第h层上的所有结点(1<=h<=k)
输出二叉树第h层上的所有结点(1<=h<=k)问题引入:已知一颗二叉链表方式存储的深度为k的二叉树,根结点是第1层。编写算法,输出第h层所有结点,1<=h<=k。分析二叉树的算法题一般都能通过递归解决,我们每次都比较当前结点是否在第h层,若在,输出其数据域的值,若不在,继续在左子树和右子树递归。核心算法:typedef struct Node { DataType data;//数据域 struct Node *leftchild;//左子树指针 struct No原创 2020-08-05 17:20:37 · 1877 阅读 · 6 评论 -
已知顺序表L中的数据元素按照递增有序排列。删除顺序表中所有大于k1且小于k2的元素
问题引入:已知顺序表L中的数据元素按照递增有序排列。删除顺序表中所有大于k1且小于k2的元素(k1<=k2)算法思想:先寻找值大于等于k1的第一个元素(第一个删除的数据元素),然后寻找值大于k2的第一个数据元素(最后一个删除的下一个元素),将后面所有结点前移即可。核心算法:#define MaxSize 50 //表长度的初始定义typedef struct{ElemType data[MaxSize]; //顺序表的元素int length; //顺序表的当原创 2020-08-03 17:29:00 · 3998 阅读 · 5 评论 -
两个单向循环链表的合并(带头结点)
两个单向循环链表的合并(带头结点)问题引入:已知两个带头结点的单向循环链表,LA和LB分别是链表的头指针,LA=(a1,a2…am),LB=(b1,b2,…bm),编写算法,将LA和LB合并成一个单项循环链表LC=(a1,a2…am,b1,b2,…bm)。核心算法:只需要修改两个表的表尾结点让两个表连起来即可。最后释放多余的LB这个头结点typedef struct node { DataType data; struct node *next;}*LSNode;//两个带头结点的单向循原创 2020-08-03 17:21:46 · 5319 阅读 · 1 评论 -
二叉排序树的平均查找长度(成功&&不成功)
二叉排序树的平均查找长度上图所示为二叉排序树查找成功时的平均查找长度:ASL=∑(本层高度*本层元素结点个数)/结点总数=(1 * 1 +2 * 2+3 * 2)=11/5查找失败时的平均查找长度:ASL=∑(本层高度*本层补上的叶子结点数)/补上的叶子节点总数=(3 * 2+4 * 4)/6=11/3...原创 2020-08-03 12:46:56 · 32426 阅读 · 6 评论 -
将顺序表中非零元素移动到顺序表的前面
一、问题引入已知长度为n的线性表A采用顺序存储结构,编写算法将A中所有的非零元素依次移到线性表A的前端二、分析直接用两个for循环解决(时间复杂度可能高了点),每查找到一个为0的位置,都在当前位置后面寻找到第一个非零元素的位置,这两个位置的元素值交换即可。三、核心代码:#define MaxSize 50 //表长度的初始定义typedef struct{ ElemType data[MaxSize]; //顺序表的元素 int length; //顺序表的当前长度原创 2020-08-01 13:19:56 · 1792 阅读 · 0 评论 -
顺序循环队列(只设尾指针和所含元素个数)
问题引入:假设以一维数组elem[0…m-1]存储循环队列的元素,同时设变量rear和quelen分别指示循环队列中队尾元素的位置和队列中所含元素个数。(1)说明该队列特点(2)给出该循环队列的队空、队满条件(3)编程实现入队列算法(4)编程实现出队列算法分析:结构体:typedef struct node { DataType elem[M]; int rear;//队尾指针 int quelen;//元素个数}SeQueue;SeQueue Q;队空条件:Q.quelen原创 2020-07-29 13:08:15 · 3713 阅读 · 1 评论 -
插入有序的单链表(要求插入后元素有序排列)
问题引入:某校实验室有一批计算机,按其价格从低到高的次序构成了一个单链表存放,链表中每个结点指出同样价格的若干台。现在又增加m台价格为h元的计算机,编程实现实验室计算机单链表中增加计算机的算法。分析这和插入排序的思想有点类似,我们直接在每次插入的时候都按照主关键字(即价格price)的顺序插,这样每次插入后都是有序的。算法实现:typedef struct node { double price;//价格 int count;//数量 struct node *next;}*SLNode;原创 2020-07-29 01:32:19 · 2988 阅读 · 0 评论 -
图的连通分量个数
一、定义: 在无向图中,如果从顶点vi到顶点vj有路径,则称vi和vj连通。如果图中任意两个顶点之间都连通,则称该图为连通图,否则,将其中的较大连通子图称为连通分量。 在有向图中,如果对于每一对顶点vi和vj,从vi到vj和从vj到vi都有路径,则称该图为强连通图;否则,将其中的极大连通子图称为强连通分量。 上面有向图的连通分量个数为2二、分析:我们给图的每个结点设置一个访问标志,用visited原创 2020-07-28 00:28:37 · 10700 阅读 · 0 评论 -
两个非递增的有序链表的合并
两个非递增的有序顺序表的合并一、问题引入:已知两个带头结点的非递增有序的单链表A和B,设计算法将两个单链表合并成一个非递增有序的单链表C.要求单链表C仍使用原来两个链表的存储空间二、分析两个链表都是有序的,我们直接将A的头节点作为结果集链表的头节点,用pa和pb作为A和B的工作指针,循环比较pa和pb的数据域,将较大值接入结果集链表的尾部就行,如果俩个链表的长度不一致,最后会有一个链表剩余,将剩余的所有结点直接接在结果集链表的尾部就ok。三、算法实现:typedef struct LNode{原创 2020-07-25 23:18:22 · 2698 阅读 · 0 评论 -
二叉树的层序遍历
二叉树的层序遍历一、定义 所谓二叉树的层次遍历,是指从二叉树的第一层(根节点开始)自上而下逐层遍历,同层内按照从左至右的顺序逐个结点访问。 由二叉树层次遍历的要求可知,当一层访问完之后,按该层结点访问的次序,再对各结点的左、右孩子进行访问(即对下一层从左到右进行访问),这一访问的特点是:先访问的结点其孩子也将先访问,后访问的结点其孩子也将后原创 2020-07-25 23:04:13 · 6668 阅读 · 0 评论 -
求二叉树中度为1的结点个数
一、问题引入已知一颗以二叉链表方式存储的二叉树,编写算法计算二叉树的单孩子的结点数。单孩子是指该结点只有左孩子或只有右孩子(其实就是求度为1的结点个数)二、算法实现typedef struct Node { DataType data;//数据域 struct Node *leftchild;//左子树指针 struct Node *rightchild;//右子树指针}BiTreeNode;用递归实现特别简单//计算二叉树中度为1的结点总数int leaf_1(BiTreeNod原创 2020-07-25 22:51:07 · 20079 阅读 · 16 评论 -
图的邻接矩阵存储结构
图的邻接矩阵存储结构一、知识框架二、存储方式(这里只讨论邻接矩阵存储方式)在图的邻接矩阵存储结构中,顶点信息使用一维数组存储,边信息的邻接矩阵使用二维数组存储。无向图和其对应的邻接矩阵有向图三、代码实现1.头文件AdjMGraph.h针对的是下面这个有向图#pragma once//图的邻接矩阵存储结构#include "SeqList.h"typedef struct { SeqList Vertices; //存放顶点的顺序表 int edge[MaxVer原创 2020-07-05 22:21:03 · 2219 阅读 · 0 评论 -
二叉树
一、二叉树的定义二叉树是n(n≥0)个结点组成的有限集合。当n=0时,称为空二叉树;当n>0时,该集合由一个根节点及两颗互不相交的,被分别成为左子树和右子树的二叉树组成。二叉树可以理解为满足以下条件的树形结构。每个结点的度不大于2结点每颗子树的位置是明确区分左右的,不能随意改变。由上述定义可看出:二叉树中的每个结点只能有0、1、2个孩子,而且孩子有左右之分,即使仅有一个孩子,也必须区分左右。位于左边的孩子(或子树)叫左孩子(左子树),位于右边的孩子(或子树)叫右孩子(右子树)二、二叉树原创 2020-06-27 12:11:04 · 734 阅读 · 0 评论 -
一维数组元素的循环右移(java实现)
一、问题描述:设以一个算法,实现将一维数组中的元素循环右移k位,要求只用一个元素大小的辅助空间。二、代码实现:(IDEA2019开发环境)package temp;import java.util.Scanner;//将数组元素循环右移k位,只能用一个额外的辅助空间//那就用第0号存储空间来辅助public class RightMove { public int[] righrmove(int[] x, int k) { k=k%(x.length);//余数是实原创 2020-06-14 17:01:47 · 2165 阅读 · 0 评论