
数据结构
文章平均质量分 77
数据结构与算法
程序员班长
武汉计算机硕士在读,热爱计算机也不想秃头
展开
-
DFS算法查找所有路径详解
深度优先搜索(Depth-First Search,DFS)是一种图遍历算法,它从起始节点开始,沿着一条路径尽可能深入,直到达到最深的节点,然后回溯到前一节点,继续探索下一条路径。DFS通常使用递归或栈(非递归)来实现。原创 2023-12-26 18:22:31 · 1200 阅读 · 0 评论 -
佛洛依德算法详解
佛洛依德算法(Floyd-Warshall Algorithm)和迪杰斯特拉算法(Dijkstra’s Algorithm)都是用于解决图的最短路径问题的算法,但它们有一些关键的区别。原创 2023-12-26 18:06:55 · 347 阅读 · 0 评论 -
迪杰斯特拉算法详解
首先要知道的是,迪杰斯特拉算法是求解单源最短路径的,就是在一个图中(无向图和有向图均可),指定一个源点,求出来这个源点到其他各个节点的最短路径。原创 2023-12-25 16:02:09 · 2427 阅读 · 0 评论 -
邻接矩阵和邻接表的相互转化
#include <iostream>#define MaxNum 100using namespace std;//邻接矩阵typedef struct{ int Vex[MaxNum]; //顶点 int edge[MaxNum][MaxNum]; //边 int arcnum,vexnum; //边和顶点个数 }MGraph; //邻接表 typedef struct ArcNode{ int adjvex; struct ArcNode *next; .原创 2020-12-24 10:51:53 · 2271 阅读 · 1 评论 -
非递归遍历求二叉排序树的深度
#include <iostream>#include <stdlib.h>#include <stdio.h>#include <queue> #define Maxsize 100using namespace std;typedef struct BTNode{ int data; struct BTNode *lchild,*rchild;}BTNode;//利用非递归中序遍历求二叉排序树的深度 int BSTDeepth(B.原创 2020-12-21 20:44:50 · 425 阅读 · 0 评论 -
利用堆排序查找数组中第K小的元素方法
先从数组A[ ]中取前k个元素建立大根堆,然后再遍历剩下的n-k个元素,如果大于或者等于堆顶,则舍弃;如果小于堆顶,则将其与堆顶替换,并将换下来的堆顶舍弃,然后重新向下调整为大根堆,最后堆顶即为所求。时间复杂度为O(nlogk)/*给定数组A[n],设计最优算法查找第k小元素,最优算法是堆排序,时间复杂度O(nlogk)*/void Adjust(A[],k,len){ int i; A[0]=A[k]; for(i=k*2;i<len;i*=2){ if(A[i]<原创 2020-12-07 21:11:53 · 1849 阅读 · 0 评论 -
超详细!各种内部排序算法的比较
先来个表格总结直观展示下:各种内部排序算法的性质 算法种类 时间复杂度 空间复 杂度 稳定性 最好情况 平均情况 最坏情况 插入排序 直接插入排序 O(n) O(n^2) O(n^2) O(1) 稳定 折半插入排序 O(n) O(n^2) O(n^2) O(1) 稳定 希尔排序 O(n^1.3) O(nlogn) ...原创 2020-11-30 15:42:40 · 2293 阅读 · 0 评论 -
堆排序分析(大根堆为例,由小到大排序)
时间复杂度为O(nlogn),思路就是从最后一个非叶结点开始,依次往回遍历每个结点,将以该结点为根的子树建立成大根堆,直到遍历到整棵完全二叉树的根结点时为止,此时整棵树为大根堆。以当前结点为根的子树建立大根堆://向下调整,将该结点的子树变成大根堆 void AdjustDown(int A[],int k,int len){ //k为根结点编号,len为数组长度 int i,j; A[0]=A[k]; for(j=2*k;j<=len;j*=2){ if(j<len&a原创 2020-11-30 10:58:33 · 3791 阅读 · 2 评论 -
让你秒懂的折半查找(二分查找)
折半查找又称二分查找,只能适用于有序的顺序表。//折半查找int Bsearch(int R[],int low,int high,int key){ int min; while(low<=high){ mid=(low+high)/2; //取中间位置 if(R[mid]==key) //查找成功 return mid; else if(R[mid]>key) high=mid-1; //从前半部分继续查找 else low=mid+1; //原创 2020-11-24 17:37:48 · 493 阅读 · 0 评论 -
DAG图之拓扑排序
拓扑排序的时间复杂度为O(V+E),其中V、E分别为顶点和边的个数。#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;typedef struct ArcNode{ //存储边 int adjvex; //该弧所指向的顶点 struct ArcNode *nextarc; //指向下一条弧 //InfoType i原创 2020-11-23 16:06:50 · 553 阅读 · 0 评论 -
最短路径-Floyd(佛洛伊德算法)
佛洛伊德算法时间复杂度为O(n^3),其中n为顶点的个数。Floyd可求出任何一对顶点之间的最短路径。允许图中有带负权值的边,但是不允许有包含带负权值的边组成的回路。#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;typedef struct{ VertexType Vex[Maxsize]; EdgeType原创 2020-11-22 21:41:37 · 839 阅读 · 0 评论 -
单源最短路径-Dijkstra(迪杰斯特拉算法)
迪杰斯特拉算法时间复杂度为O(n^2),其中n为顶点个数。该算法用于求单源最短路径。#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;typedef struct{ VertexType Vex[Maxsize]; EdgeType edge[Maxsize][Maxsize]; int vexnum,arcnu原创 2020-11-22 21:30:49 · 392 阅读 · 0 评论 -
求最小生成树-Kruskal(克鲁斯卡尔算法)
克鲁斯卡尔算法时间复杂度与排序算法sort有关,适合于稀疏图。#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;typedef struct{ VertexType Vex[Maxsize]; EdgeType edge[Maxsize][Maxsize]; int vexnum,arcnum;}MGraph;typ原创 2020-11-21 20:45:22 · 297 阅读 · 0 评论 -
求最小生成树-Prim(普里姆算法)
普里姆算法时间复杂度为O(V^2),适用于稠密图#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;type struct{ VertexType Vex[Maxsize]; EdgeType edge[Maxsize][Maxsize]; int vexnum,arcnum;}MGraph;//Prim-普里姆算法原创 2020-11-21 20:29:07 · 237 阅读 · 0 评论 -
Floyd-傻子也能看懂的弗洛伊德算法
暑假,小哼准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有,如下图。为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程。 上图中有4个城市8条公路,公路上的数字表示这条公路的长短。请注意这些公路是单向的。我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径。这个问题这也被称为“多源最短路径”问题。 现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4...转载 2020-11-21 19:25:02 · 3751 阅读 · 6 评论 -
BFS求无权图的单源最短路径-邻接矩阵存储
//邻接矩阵存储void BFS_MIN-Distance(Graph G,int u){ //d[i]表从u到i的最短路径 for(i=0;i<G.vexnum;i++) d[i]=INT_MAX;//无穷大 visited[u]=True; d[u]=0; EnQueue(&Q,u); while(!IsEmpty(Q)){ DeQueue(&Q,u); for(w=FirstNeighbor(G,u);w>=0;w=NextNeighbor(G,u.原创 2020-11-18 20:41:32 · 828 阅读 · 0 评论 -
利用邻接表完成图的BFS和DFS
#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;typedef struct ArcNode{ //存储边 int adjvex; struct ArcNode *nextarc;}ArcNode;typedef struct VNode{ VertexType data; ArcNode *firstarc;.原创 2020-11-17 22:29:06 · 260 阅读 · 0 评论 -
利用邻接矩阵实现图的BFS和DFS
#include <iostream>using namespace std;#define Maxsize 100typedef char VertexType;typedef int EdgeType;type struct{ VertexType Vex[Maxsize]; EdgeType edge[Maxsize][Maxsize]; int vexnum,arcnum;}MGraph;bool visited[Maxsize];void BFS(MGra.原创 2020-11-17 22:27:52 · 354 阅读 · 0 评论 -
利用栈完成中缀表达式到后缀表达式的转换
From王道数据结构原创 2020-09-12 16:46:04 · 290 阅读 · 0 评论 -
基数排序
空间复杂度:O(r),r为队列的个数,同时也是基数的值,如果每位取值为0~9,则r=10时间复杂度:O(d(n+r)),d为位数,比如每个数字有百位、十位和个位,则d=3,n为数字的个数,r为队列的个数稳定性:稳定...原创 2020-08-23 11:29:46 · 266 阅读 · 0 评论 -
归并排序
空间复杂度:O(n)时间复杂度:O(nlogn)稳定性:稳定//归并排序int *B=(int *)malloc((n+1)*sizeof(int)); //构造辅助数组Bvoid Merge(int A[],int low,int high,int mid){ //二路归并 for(int k=low;k<=high;k++){ B[k]=A[k]; //将待排序的元素复制到B中 } for(i=low,j=mid+1,k=i;i<=mid&&am原创 2020-08-23 11:10:37 · 244 阅读 · 0 评论 -
两种选择排序算法:简单选择排序、堆排序
一、简单选择排序空间复杂度:O(1)时间复杂度:O(n^2)稳定性:不稳定适用性:顺序表、链表//简单选择排序void SelectSort(int A[],int n){ for(i=0;i<n-1;i++){ min=i; for(j=i+1;j<n;j++){ if(A[j]<A[min]) min=j; } if(min!=i) swap(A[i],A[min]); }}二、堆排序空间复杂度:O(1)时间原创 2020-08-21 23:45:48 · 328 阅读 · 0 评论 -
两种交换排序算法:冒泡排序和快速排序
一、冒泡排序空间复杂度:O(1)时间复杂度:最好O(n),最坏和平均为O(n^2)稳定性:稳定适用性:顺序表、链表//冒泡排序void BubbleSort(int A[],int n){ for(i=0;i<n-1;i++){ flag=false; //本趟是否发生了交换 for(j=n-1;j>i;j--){ if(A[j]<A[j-1]){原创 2020-08-20 22:38:47 · 296 阅读 · 0 评论 -
三种插入排序算法:直接插入排序、折半插入排序、希尔插入排序
一、直接插入排序空间复杂度:O(1)时间复杂度:O(n^2)稳定性:稳定适用性:顺序表和链表//直接插入排序void InsertSort1(int A[],int n){ int i,j,temp; for(i=1;i<n;i++){ if(A[i]<A[i-1]){ temp=A[i]; for(j=i-1;j>=0&&A[j]>temp;j--){原创 2020-08-18 22:52:10 · 486 阅读 · 0 评论 -
DFS实现逆拓扑排序
多思考递归的过程!//DFS实现逆拓扑排序bool visited[MaxVertexNum];void DFSTraverse(Graph G){ for(v=0;v<G.vexnum;v++) visited[v]=FALSE; for(v=0;v<G.vexnum;v++) if(!visited[v]) DFS(G,v);}void DFS(Graph G,int v){ visit(v);.原创 2020-08-06 18:43:53 · 1075 阅读 · 1 评论 -
图的两种遍历算法——BFS和DFS
一、BFS,也称广度优先搜索,和二叉树的层次遍历算法类似//BFSbool visited[MaxVertexNum];void BFSTraverse(Graph G){ for(i=0;i<G.vexnum;i++) visited[i]=FALSE; InitQueue(Q); for(i=0;i<G.vexnum;i++) if(!visited[i]) BFS(G,i);}void BFS(G原创 2020-08-05 14:43:04 · 697 阅读 · 0 评论 -
图的邻接矩阵存储和邻接表存储定义方法
一、邻接矩阵#include <iostream>using namespace std;#define MaxVertexNum 100 //顶点最大数目//邻接矩阵存储结构typedef struct{ char Vex[MaxVertexNum]; //顶点表 int Edge[MaxVertexNum][MaxVertexNum]; //边表 int vexnum,arcnum; //图当前顶点数原创 2020-08-05 14:37:20 · 748 阅读 · 0 评论 -
递归和非递归实现二叉排序树(BST)的查找操作
二叉排序树又称二叉查找树非递归实现BST的查找操作空间复杂度为O(1),但是递归实现的空间复杂度为O(h),h为树的高度#include <iostream>using namespace std;typedef struct BSTNode{ int key; struct BSTNode *lchild,*rchild;}BSTNode,*BSTree;//非递归,空间复杂度为O(1)BSTNode *BST_Search(BSTree T,int k.原创 2020-07-28 19:46:51 · 622 阅读 · 0 评论 -
树和森林转二叉树,二叉树无右孩子(或右指针域为空)的结点个数计算思路
前提是知道非终端结点(分支结点)的个数,假设非终端结点的个数为n1.对于树转二叉树:因为转化规则是“左孩子右兄弟”,如果有n个分支结点,因为每个分支结点都会有孩子,这些孩子都是兄弟,然而最右边的孩子已经没有右兄弟了,没有右兄弟就意味着在转化为二叉树后这个孩子没有右孩子——即右指针域为空。又因为每个分支结点都存在一个没有右兄弟的孩子,所以n个分支结点就存在n个没有右兄弟的孩子,在转化为二叉树后这些孩子的右指针域都为空。最后,不要忘记树的根结点是没有兄弟的,所有在转化为二叉树后根结点的右指针域也原创 2020-07-27 22:51:13 · 8869 阅读 · 13 评论 -
先序序列为a、b、c、d的不同二叉树的个数是多少(卡特兰数)
除了逻辑清晰的挨个画出来之外,还有一种方法需要大家牢记!因为前序序列和中序序列可以唯一地确定一棵二叉树,并且题目已经给出了先序序列,所以我们只需要知道由该先序序列可以确定多少个中序序列即可,确定多少个中序序列就是可以确定多少棵二叉树!那么,问题来了,由一个先序序列如何确定有多少个中序序列呢?这就有两个“公式”需要大家去牢记了!1、先序序列和中序序列的关系为:以先序序列入栈,则出栈序列必为中序序列。2、一个入栈顺序可以确定的出栈顺序为C(2n,n) / (n+1)(卡特兰数)。..原创 2020-07-26 18:59:29 · 21788 阅读 · 8 评论 -
二叉树的先序线索化、中序线索化、后序线索化的对比
有一点需要注意:在先序遍历一个节点的左子树时,需要判断其ltag的值是否为0,如果为0可以正常遍历,但是,如果为1就不能进行遍历。因为ltag的值为1说明该结点的左指针指向的是它的前驱结点而不是左孩子(左孩子其实并不存在),继续遍历的话就会陷入“转圈圈”(前驱结点、该结点、前驱结点、该结点……)因为在中序遍历的顺序为左孩子、跟结点、右孩子,后序遍历的顺序为左孩子、右孩子、根结点。在遍历到跟结点时它的左孩子肯定是已经被遍历过了,不存在上述“转圈圈”的问题,所以可以正常遍历。右指针要么指向右孩子,要么指原创 2020-07-25 15:48:52 · 2675 阅读 · 6 评论 -
二叉树的四种遍历方法:前序、中序、后序、层次
前/中/后序遍历也可分别称为前/中/后根遍历#include <iostream>using namespace std;//二叉树的链式存储的结点typedef struct BiTNode{ int data; struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;//链式队列结点typedef struct LinkNode{ BiTNode *data; struct LinkNode *ne原创 2020-07-25 00:00:49 · 218 阅读 · 0 评论 -
串的模式匹配、KMP算法、nextval数组求法
一、暴力匹配#include <iostream>using namespace std;#define MAXLEN 255typedef struct{ char ch[MAXLEN]; int length;}SString;//S为主串,T为子串//暴力匹配int Index(SString S,SString T){ int i=1,j=1; int k=1; while(i<=S.length &&原创 2020-07-17 23:50:53 · 588 阅读 · 0 评论 -
稀疏矩阵的压缩存储的两种策略
来自王道数据结构原创 2020-07-15 22:15:32 · 550 阅读 · 0 评论 -
三对角矩阵(带状矩阵)的压缩存储原理
来自王道数据结构原创 2020-07-15 22:13:28 · 3416 阅读 · 0 评论 -
分别用顺序表和链表实现队列
一、顺序表实现队列#include <iostream>using namespace std;#define MaxSize 50typedef struct{ int data[MaxSize]; int front,rear;}SqQueue;void InitQueue(SqQueue &Q){ Q.front=Q.rear=0;}bool IsEmpty(SqQueue Q){ if(Q.front==Q.rear)原创 2020-07-11 23:00:12 · 206 阅读 · 0 评论 -
数据结构—分别用头插法和尾插法建立单链表
#include <iostream>using namespace std;typedef struct LNode{ int data; struct LNode *next;}LNode,;*LinkList;//头插法LinkList List_HeadInsert(LinkList &L){ LNode *s; int x; L=(LinkList)malloc(sizeof(LNode)); L->next=.原创 2020-07-07 23:37:25 · 574 阅读 · 0 评论 -
将两个有序表合并为一个
#include <iostream>using namespace std;#define Maxsize 20typedef struct{ int length; int data[Maxsize]; int maxSize;}SqList;bool Merge(SqList A,SqList B,SqList &C){ if(A.length+B.length>C.maxSize) return false;.原创 2020-07-05 22:45:28 · 210 阅读 · 0 评论 -
删除有序表中重复的元素,注意是有序表!
#include <iostream>using namespace std;#define Maxsize 20typedef struct{ int data[Maxsize]; int length;}SqList;void Del_repeat(SqList &L){ int i,k=0,temp=L.data[0]; for(i=1;i<L.length;i++) { if(L.data[i]==te.原创 2020-07-05 21:26:16 · 251 阅读 · 0 评论 -
三种方法删除有序表中s和t直接的元素(包含s和t)
#include <iostream>using namespace std;typedef struct{ int data[10]={0,1,2,3,4,5,6,7,8,9}; int length=10;}SqList;//解一bool Del_s_t(SqList &L,int s,int t){ if(L.length==0||s>=t) return false; int k=0; for(int.原创 2020-07-04 23:23:59 · 459 阅读 · 0 评论