
数据结构与算法
数据结构学习历程记录
tanxinji
站在巨人的肩膀上
展开
-
图用邻接表表示的深度优先和广度优先遍历
然后,从队列中取出一个顶点进行处理,输出其数据,并将其所有未访问的邻接顶点入队并标记为已访问。它首先将当前顶点标记为已访问,并输出顶点的数据。然后,遍历当前顶点的邻接表,对于每个未被访问过的邻接顶点,递归调用。广度优先遍历(Breadth-First Search,BFS)是一种图遍历算法,它以广度优先的顺序遍历图的所有节点。,每个顶点表项存储了顶点的数据和指向第一个邻接顶点的指针。函数用于遍历图中所有顶点,并对未访问过的顶点调用。,存储了邻接顶点的下标和指向下一个邻接顶点的指针。函数进行深度优先遍历。原创 2023-12-19 23:18:20 · 846 阅读 · 0 评论 -
队列的基本操作以及C语言实现
1.Enqueue:将元素插入队列尾部。2.Dequeue:从队列头部移除元素。4.IsEmpty:检查队列是否为空。5.IsFull:检查队列是否已满。3.Front:获取队列头部元素。原创 2023-10-19 00:00:00 · 356 阅读 · 0 评论 -
栈的基本操作以及C语言实现
4.IsEmpty:检查栈是否为空。5.IsFull:检查栈是否已满。1.Push:将元素压入栈顶。2.Pop:从栈顶弹出元素。3.Top:获取栈顶元素。原创 2023-10-18 19:00:00 · 297 阅读 · 0 评论 -
求解哈夫曼树HuffmanTree以及C语言实现
对于每个字符,创建一个节点,并将该节点插入到优先队列中。节点的频率可以是字符在文本中出现的次数或者其他预定义的权重。从优先队列中提取出两个频率最小的节点作为左右子节点,并创建一个新节点作为它们的父节点。将新节点插入优先队列中。在压缩数据时,出现频率较高的字符被编码为较短的二进制码,而出现频率较低的字符则被编码为较长的二进制码,以达到压缩数据的目的。PriorityQueue表示优先队列,用于构建哈夫曼树,包含队列的大小、容量和节点指针数组。最小堆是一种二叉树,其中每个节点的值都小于或等于其子节点的值。原创 2023-10-13 19:00:00 · 432 阅读 · 0 评论 -
Dijkstra算法和Floyd算法求最短路径以及C语言实现
①初始化距离数组和访问数组,将起始节点的距离值设置为0,其他节点的距离值设置为无穷大,访问数组初始化为false。②从起始节点开始,选择当前距离值最小的节点,将其标记为已访问。③遍历该节点的邻居节点,如果通过当前节点到达邻居节点的路径比之前的路径更短,则更新邻居节点的距离值。④重复上述步骤,选择下一个距离值最小的未访问节点,直到所有节点都被标记为已访问,或者找到了目标节点。②使用动态规划的思想,通过中间节点的遍历来更新节点之间的最短路径。如果通过中间节点得到的路径比之前的路径更短,则更新距离矩阵中的值。原创 2023-10-12 19:00:00 · 338 阅读 · 0 评论 -
Prim算法和Kruskal算法求最小生成树以及C语言实现
算法思想:从一个顶点开始构建最小生成树,每次选择一个键值最小的顶点加入最小生成树,并更新与该顶点相邻的顶点的键值。最终得到的最小生成树是连接所有顶点并具有最小总权重的树。算法思想:将图的所有边按照权重进行排序,然后依次选择权重最小的边,如果选择该边不会形成环路,则将其加入最小生成树,直到最小生成树的边数达到 V-1。①选择权重最小的边,如果该边的两个顶点不在同一个连通分量中,则将该边加入最小生成树集合,并合并两个连通分量。①从最小生成树集合连接到顶点集合的边中选择权重最小的边。原创 2023-10-07 14:14:31 · 373 阅读 · 0 评论 -
计算后缀表达式的值以及C语言实现
遇到 * 运算符,从栈中弹出 31 和 5,计算 31 * 5 = 155,将 155 入栈。遇到 + 运算符,从栈中弹出 7 和 24,计算 7 + 24 = 31,将 31 入栈。遇到 * 运算符,从栈中弹出 8 和 3,计算 8 * 3 = 24,将 24 入栈。②如果是运算符,从栈中弹出两个操作数,进行相应的运算,并将结果入栈。后缀表达式5 3 8 * 7 + *的计算结果为栈顶元素 155。遍历到 5,将 5 入栈。遍历到 3,将 3 入栈。遍历到 8,将 8 入栈。遍历到 7,将 7 入栈。原创 2023-10-08 08:00:00 · 1166 阅读 · 0 评论 -
Java 求数的范围
题目:给定一个按照升序排列的长度为 nn 的整数数组,以及 qq 个查询。对于每个查询,返回一个元素 kk 的起始位置和终止位置(位置从 00 开始计数)。如果数组中不存在该元素,则返回 -1 -1。输入格式第一行包含整数 nn 和 qq,表示数组长度和询问个数。第二行包含 nn 个整数(均在 1∼100001∼10000 范围内),表示完整数组。接下来 qq 行,每行包含一个整数 kk,表示一个询问元素。输出格式共 qq 行,每行包含两个整数,表示所求元素的起始位置和终原创 2022-01-17 20:55:46 · 571 阅读 · 1 评论 -
Java 求一个数的二进制第n位是否为1
很简单。设数为num,将num右移n-1位在&1 ,如果num>>(n-1)&1为1,第n位为1,num>>(n-1)&1为0,第n位为0。 求第1位是否为1则就是 num &1即可。 为何要右移>>(n-1):将第n位数变到个位,这样方便&1运算。&1也是和个位数&。 为何要&1。逻辑& : 0&0 = 0 , 0&1 =0 , 1&1 = 1;只有1&1原创 2022-02-09 01:27:56 · 1852 阅读 · 0 评论 -
Java 如何将数组所有元素转换成一个数
只适用于数组每一个下标存的是一位数,并且是有序的,如某个数组存的是 百十个位,或者个十百位。一、将数组元素转换成一个数 设num是要转换的数 num = num*10 + array[i] ; i = 0~n-1。 乘以十是为了提高数的位数,每次加的数组元素是当前num的个位。从在数组中所认为的数的个位开始加。 代码示例:public class Test { public static void main(String[] args) { int array[] = {5原创 2022-02-08 20:55:53 · 3974 阅读 · 0 评论 -
Java求区间和
前缀和可以通过O(1)的算法复杂度来求一个区间的和。设 q为一个数组,用S来存储q数组对应下标的前n项和。如果要求下标n~m区间的q数组的和。就是用 S[m]-S[n-1] 来得到,用前m项的和S[m]减去前n-1项的和,从而得到区间m~n的和。 代码实例: 输入n,m。输入n个数。然后输入m个x,y。输出x~y的区间和。import java.util.*;public class Main{ public static void main(String[]args){原创 2022-02-21 20:00:23 · 1049 阅读 · 0 评论 -
求两个数的最小公倍数
求两个数的最小公倍数可以转换成 求两个数的绝对值乘积/两个数的最大公约数。 设gcd(a,b)表示a,b的最大公约数。lcm(a,b)表示a,b的最小公倍数。 则存在 : lcm(a,b) * gcd(a,b) = |a*b|。可能lcm(a,b) = |a*b| / gcd(a,b) 计算模板: int gcd(int a, int b) { //求最大公约数 return b!=0?gcd(b,a%b):a; } int lcm = Math.abs(a,b) /原创 2022-02-22 14:43:56 · 794 阅读 · 0 评论 -
Java 递归求九九乘法表
首先看一下两层for循环求。public class Main { public static void main(String[] args) { for(int i = 1;i<=9;i++){ for(int j = 1;j<=i;j++){ System.out.print( i+" * "+j+" = "+i*j+"\t" ); } System.out原创 2022-03-04 10:53:03 · 717 阅读 · 0 评论 -
Java 求二进制中的1的个数
题目:给定一个长度为nn的数列,请你求出数列中每个数的二进制表示中11的个数。输入格式第一行包含整数nn。第二行包含nn个整数,表示整个数列。输出格式共一行,包含nn个整数,其中的第ii个数表示数列中的第ii个数的二进制表示中11的个数。数据范围1≤n≤1000001≤n≤100000,0≤数列中元素的值≤1090≤数列中元素的值≤109输入样例:51 2 3 4 5输出样例:1 1 2 1 2 ...原创 2022-01-14 22:53:06 · 1068 阅读 · 0 评论 -
将所有取负值的关键字排在所有取正值(非负值)的关键字之前
试设计一个算法, 使得在O(n)的时间内重排数组, 将所有取负值的关键字排在所有取正值(非负值)的关键字之前。 快排的思想,从n-1开始依次递减找到一个大于0的,从0开始依次递增找到一个小于0的,交换。就OK了。int partition(int num[],int low,int high){ while(low<high){ while(low<high&&num[high]>0){ hi...原创 2021-07-03 19:35:31 · 2356 阅读 · 8 评论 -
C/C++求汉诺塔递归深度,步数,移动的轨迹
盘子为1~n,柱子号为1 2 3.从1号n个盘子,递归后有序放在3号。 代码:#include <iostream>using namespace std;int n ;int count = 1 ;void move(int disk , int a , int b){ printf("深度:%d,步数:%d,盘子:%d 从%d -> %d\n",n-disk+1,count,disk,a,b); count++;}void hanoi(int disk ,原创 2022-03-29 07:00:00 · 507 阅读 · 0 评论 -
Java 求走迷宫的最小步数(bfs)
使用bfs可以求走迷宫从起始点到目标点的最小步数和路径。题目 题目链接811.走迷宫题目:给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。输入格式第一行包含两个整数原创 2022-02-07 19:27:22 · 674 阅读 · 0 评论 -
Java 用Floyd算法求多源最短路
设d[i][j]存储的是i到j的最短路径。初始化时当 i == j将d[i][j] = 0;当i!=j时,d[i][j] = 正无穷。正无穷可以是1e9。 使用Floyd求最短路的算法复杂度为O(n3),三层for循环。 核心代码:for(int kk=1;kk<=n;kk++){ for(int i = 1;i<=n;i++){ for(int j = 1;j<=n;j++){ d[i][j] = Math.min(d[i][j],d[i][原创 2022-02-22 11:06:46 · 201 阅读 · 0 评论 -
Java 求数字三角形
题目:给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。 7 3 8 8 1 0 2 7 4 44 5 2 6 5输入格式第一行包含整数 nn,表示数字三角形的层数。接下来 nn 行,每行包含若干整数,其中第 ii 行表示数字三角形第 ii 层包含的整数。输出格式输出一个整数,表示最大的原创 2022-01-17 23:36:59 · 867 阅读 · 3 评论 -
Java 求摘花生
题目:AcWing 1015. 摘花生Hello Kitty想摘点花生送给她喜欢的米老鼠。她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。Hello Kitty只能向东或向南走,不能向西或向北走。问Hello Kitty最多能够摘到多少颗花生。1.gif输入格式第一行是一个整数T,代表一共有多少组数据。接下来是T组数据。每组数据的第一行是两个整数,分别代表花生苗的原创 2022-01-28 17:01:41 · 226 阅读 · 0 评论 -
Java 求数的全排列(dfs)
如何求n个元素的全排列,如1 2 3的全排列为 1 2 3 ; 1 3 2 ; 2 1 3; 2 3 1; 3 1 2 ; 3 2 1; 使用的是递归,暴力搜索所有可行的方案。可以用一个一维数组存储每次找到的一种方案。一、求1~n的全排列 代码示例:// 输出一个n,输出1~n的全排列import java.util.*;public class Main{ static int N = 10; static int n ; static int path[] = n原创 2022-02-07 00:07:27 · 3678 阅读 · 0 评论 -
判断素数,素数筛
一、判断一个数是否为素数 判断一个数是否是素数用到的是如下判别法: 如果大于1的整数a不能被所有不超过a\sqrt{a}a的素数整除,那么a一定是素数。 代码://判断a是否为素数,是返回true,不是返回falseboolean isPrime(int a){ if(a<=1){ return false; } for(int i =2 ; i <= Math.sqrt(a) ;i++){原创 2022-02-23 18:50:09 · 309 阅读 · 0 评论 -
bfs宽度优先搜索
一、bfs概述 bfs用到的是队列。首先把起始点加入队列并且移除起始点,寻找起始点开始周围可以遍历的点,加入队列中。继续取出队首,按照上述往复,直到遍历完全。 判断重复 : 当我们bfs遍历的时候,可能会遍历到重复的点,我们设置一个boolean数组st来判断是否遍历重复的点。每次将某点加入队列后,将该点的st数组设为true,当做该点已经遍历过。 求最小步数:bfs可以用来求最小步数。每次从当前点(a,b)到下一个点(x,y),那么可以认为起始点 到 下一个点的步数为 (x,y) = (a,b)+原创 2022-02-06 22:38:10 · 206 阅读 · 0 评论 -
Java 求最大公约数
求最大公约数用到的是辗转相除法原创 2022-02-02 12:52:05 · 779 阅读 · 0 评论 -
求解等差数列公式
例如如下等差数列a: 2 4 6 8 10 。首项a1为2 , 末项an为10,项数n为5。公差d为2 。等差数列和Sn为30。1、公差: d = (第n项值-第k项值) / (n-k) 。 d = (an-ak)/(n-k) 如2 4 6 8等差数列中第二项减第一项求公差就是 d = (d2-d1) = 4-2=22、第n项值: 首项+(n-1)*公差 。 an = a1+(n-1)*d 如求2 4 6 8等差数列中第二项的值: a2 = a1+d = 2+2 = 43、前n项和:原创 2022-02-02 00:45:02 · 4995 阅读 · 0 评论 -
01背包问题疑惑解决
其中我们用到的 f[i][j] 指的是背包在考虑了每次放或者不放物品,前i次物品后,背包最大容量为j体积下的最大价值,i和j可以随时变。因此通过f[][]可以获得任意i,j情况下的最大价值。每一次遍历的f[i][j]就可以认为是当前情况下的最好情况,也就是最大价值。import java.util.*;public class Main{ public static void main(String[]args){ int N = 1005; Scan原创 2022-01-28 00:59:29 · 346 阅读 · 0 评论 -
Java 快速排序模板
import java.util.*;public class Main{ public static void quick_sort(int nums[],int low ,int high){ if(low<high){ int temp = partition(nums,low,high); quick_sort(nums,low,temp-1); quick_s...原创 2022-01-16 19:28:06 · 493 阅读 · 0 评论 -
必须知道的冒泡排序
了解一下冒泡排序是什么,冒泡排序跟快排一样都是交换排序,n个元素中通过每次遍历比较j 与 j+1下标数据比较,如果不符合排序规则进行交换,进行n次来回,每次来回从头开始比较。就是两两相互比较,然后考虑吧是否交换。当然,这里也有很多重复的操作,接下来会慢慢优化。当然不可避免的是冒泡排序时间复杂度为n的平方是没的跑的,不过也可以消除重复操作优化代码。下面给出一个不需要考虑任何细节的冒泡排序,就像上述介绍冒泡排序的一样,我们就从头到n以此前后两两比较,来回走n次,如果不符合排序规则交换两个数。pu原创 2021-06-15 21:54:08 · 386 阅读 · 2 评论 -
用邻接矩阵创建图
用一个字符数组vexs[]存储着图的所有顶点,在用一个二维数组arcs[][]存储边的关系,这就是邻接矩阵。另外v表示图的顶点数,e表示图的边数。w表示某条边的权值对于arcs[i][j]二维数组存储边的关系中,数组的i,j一般都是图的顶点数,即i = j = v;并且例如arcs[i][j] = w 就可以表示为,图存在顶点vexs[i] 到顶点vexs[j]的边,并且权值为w;另外对于arcs[i][j]随着边的不同可以自行定义其规则。1.当i = j的时候,arcs[i][j]的权值2原创 2021-06-06 23:04:33 · 3290 阅读 · 0 评论 -
二叉树递归的应用
二叉树通过递归实现基本应用定义一个二叉树结构体:typedef struct bitNode{ char data; struct bitNode *lchild; struct bitNode *rchild;}bitNode,* biTree;1.创建二叉树void creatTree(bitNode *& root) //记得加&{ //认为输入的二叉树为前序遍历字符串 //以输入的字符串:AB#C##D#EF###为例 //输入#则认为该节点为原创 2021-05-27 21:05:05 · 417 阅读 · 2 评论 -
Java实现单链表
实现一个可以用任意对象为结点的单链表。嘻嘻,埋伏笔了。因为我是用内部类来实现结点的操作(Java-内部类),和用上一篇文章的Student类来作为本链表的结点的测试案例,另外还有一个如何删除对象结点,哈哈,也是上一篇的,为了防止可能看不懂,记得去看看上一篇的文章哦(Java继承原来就是这样)。创建的任意类对象的实例可以成为单链表的结点,这里也用到的就是一点点泛型的知识。另外提一下,如何解决我的那篇多态的文章的向下转型带来的不安全性就是可以用泛型解决的啦(Java多态到底教了我干啥?)。一开始以为单链表只原创 2021-05-24 20:27:28 · 3053 阅读 · 7 评论 -
将中缀表达式转换成后缀表达式并求值(栈)
中缀表达式转换成后缀表达式需要用到的是数据结构中的一种——栈。中缀表达式 : 生活中进行正常加减乘除计算的表达式。如2+(3*4-6/2)。也就是算术表达式后缀表达式 :也叫逆波兰表达式。只有运算符和数字没有括号,运算符的先后顺序存在优先级的关系。如: 234*62*2+ 。(由于需要处理字符串的原因,目前只有个位数的算术运算)给出的算术表达式通过代码实现很难计算出来,而转换成了后缀表达式的就很容易实现出来了。当然,以下代码是很容易的出计算结果的。public class Main原创 2021-05-04 20:01:12 · 4249 阅读 · 0 评论 -
头插法和尾插法创建单链表
首先声明一个单链表结构体。typedef struct LNode{ int data; struct LNode * next;}LNode,*LinkNode;链式存储如何一次性存储足够多的数据,顺序表是直接通过索引遍历赋值就可以直接完成。#include<iostream>using namespace std;#define MaxSize 10typedef struct SqList{ int data[MaxS...原创 2021-05-04 00:24:42 · 1503 阅读 · 0 评论 -
数据结构-栈
栈是一种只能在一端进行插入和删除操作的线性表,具有“后进先出”的特点。 首先定义一个结构体顺序栈:typedef int ElemType;typedef struct{ //用一个data数组要存储栈内的元素(数组下标从0开始) ElemType data[MaxSize]; //压入栈的元素 //用一个整型变量top记录栈顶的位置 int top; //栈顶的位置(当前数组元素的最大下标)}SqStack;接下来实现栈的基本功能...原创 2021-04-02 19:54:49 · 2529 阅读 · 0 评论 -
将十进制转换成m进制(顺序栈)
将十进制转换为m进制,采用的是辗转相除法,将要转换的十进制数除以m进制,每次相除的余数压入栈中,在如果商不为0,在将上一步相除得到的商在除以m进制,得到的余数压入栈中。知道商为0最后在将栈中的元素依次出栈。 题目:输入一个10进制的数n,输入要转换为m进制。输出n为m进制时的数。#include<iostream>using namespace std;#define MaxSize 100typedef struct { int data[Max...原创 2021-04-24 17:30:06 · 1567 阅读 · 0 评论