![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
数据结构与算法
文章平均质量分 64
学习数据结构与算法
MMMM_zzzz
这个作者很懒,什么都没留下…
展开
-
[C++]加权有向图 求任两顶点之间的最短有向路径 (Floyd算法)
Floyd算法和Dijkstra算法都可以用于计算加权有向图中两顶点之间的最短路径,但是Floyd算法要相对简单许多,而且当该算法完成时,我们可以得到图中任两点之间的最短路径。算法实现我们通过先限制任两点之间可经过的顶点来计算此时的最短路径,然后逐渐放宽这一限制,最终允许这两点之间的路径经过任何顶点,从而确定这两点在整张图上的最短路径。用二维数组minDistance来记录两点之间的有向最短路径长度,用k来描述经过顶点的限制,小于等于k的顶点是允许经过的顶点。起初k=0,表示两点间的最短路径不允许经过原创 2021-01-02 23:14:35 · 1476 阅读 · 0 评论 -
[C++]跳表
跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。跳表是有序链表,当一个新节点加入跳表时,会按照一定的概率分布获得一个索引等级,高等级的产生几率小于低等级。每个节点有一组next指针,各个等级的节点构成各个等级的链表,每个节点不同的next指针用于不同等级的链表,高等级的节点也都会出现在低等级的链表中,即高等级链表是低等级链表的子集。例如二分跳表,所有节点都出现在0级链表中,而只有1/2的节点出现在1级链表中,有1/8的节点出现在2级链表中……设相邻等级高等级与低等级出现率的比值为p,(原创 2021-01-02 15:07:46 · 430 阅读 · 0 评论 -
[C++]最大HBLT
堆在数组中是隐式存储的,在时间和空间上都具有极大的优势。但是若要进行两个堆的合并操作,数组描述的堆就难已完成,于是引入链式描述的左高树。左高树分为高度优先的左高树HBLT和重量优先的左高树WBLT,本文只涉及HBLT。对于一棵二叉树,引入概念外部节点,它表示树中的所有空子树。引入函数s(x),它表示根节点x到达其子节点的外部节点的最短距离。由该定义可知,如果根节点x的左子树或右子树为空,说明x直接与外部节点相连,则s(x)=1;而若s(x)=k,则说明x之下的(k-1)层都是不存在任何外部节点,即都被内部原创 2021-01-01 23:58:51 · 664 阅读 · 0 评论 -
[C++]归并排序(链表描述)
基本思想分而治之:通过递归把一个无序链表对半分成许多小链表,然后对这些小链表两两之间进行归并(合并有序链表),从而最终使整个链表有序。代码#include<iostream>using namespace std;template<class T>struct chainNode//定义链表节点{ T element; chainNode<T>* next; chainNode(const T& theElement) { next原创 2020-12-14 23:52:32 · 232 阅读 · 0 评论 -
[C++]AVL搜索树 查找/插入/删除
AVL搜索树同时具有AVL树和搜索树的性质,相当于一种把高度控制在O(log n)的搜索树,从而保证了查找、插入、删除的时间都为O(log n)。AVL树保证对于树中的任意节点,其两子树的高度之差不大于1,于是引入平衡因子这一概念。平衡因子表示一个节点的左子树的高度减去右子树的高度。也就是说,正常的AVL搜索树的任一节点,其平衡因子为1,0或-1,而当插入或删除了节点之后,树中出现某些节点平衡因子可能会变为2或-2,此时需要调整树的平衡。现在假设节点nodeX是距离插入/删除位置最近、且平衡因子为2或-原创 2020-12-13 17:41:24 · 723 阅读 · 0 评论 -
[C++]加权无向图的最小生成树 Kruskal算法与Prim算法
最小生成树:连通加权无向图的一个连通子图,满足边的数量为顶点个数n减一,且所有边的权值之和最小。Kruskal算法初始化生成树为空,将所有边存入小根堆中,然后循环取出权值最小的边,如果取出的边放入生成树后不会在树中产生环,那么就将这条边加入生成树,若产生环,则将这条边丢弃。当加入生成树的边数到达(n-1)时,循环停止,此时生成树就是最小生成树;若生成树的边数未到达(n-1)而小根堆已空,说明无法产生最小生成树。如何判断加入边之后生成树是否有环:加入边之后产生环的前提是加入边之前边的两顶点v1,v2在生原创 2020-12-11 18:51:49 · 977 阅读 · 0 评论 -
[C++]加权有向图 求一个顶点到其他各个顶点的最小加权路径(Dijkstra算法)
最小加权路径:加权有向图两顶点之间权值之和最小的路径(以下称为最短路径)。注意到一个事实:如果已知从顶点A到B的最短路径,而这条路径经过顶点C,则从A到C的最短路径一定在这条最短路径上(反证可知)。进一步,如果C是从A到B最短路径上经过的倒数第二个顶点,即经过C的下一个顶点是B,那么AB最短路径=AC最短路径+CB。基于以上事实,如果从源顶点A到目标顶点B1、B2、B3……Bn的最短路径都已知,现在加入一个新目标顶点B(n+1),那么从A到B(n+1)的最短路径是[AB1最短路径+B1B(n+1)]、[原创 2020-12-09 22:01:58 · 1668 阅读 · 0 评论 -
[C++]有向图(邻接链表描述)
有向图的所有顶点使用整数1~n表示,对于每一个顶点,都有若干条有向边从该顶点出发,到达其他顶点,这些有向边的终点称为该顶点的邻接顶点。对于每一个顶点,都可以使用一条链表来记录它的所有邻接顶点,这条链表称为邻接链表。而有向图的所有顶点构成一个数组,所以所有顶点对应的邻接链表也构成了一个链表类型的数组。邻接链表描述的有向图和邻接矩阵描述的有向图大多数函数都大同小异,本文对函数逻辑不做详细描述。以下代码主要为邻接链表描述下的有向图判断边是否存在、插入边、删除边、广度优先搜索、深度优先搜索。关于有向图的更多阐述原创 2020-12-06 23:34:45 · 2066 阅读 · 1 评论 -
[C++]有向图(邻接数组描述)
基本概念有向图主要包含两部分:顶点和有向边。本文顶点使用整数1~n表示,有向边使用邻接矩阵记录。邻接矩阵a为(n+1)*(n+1)的二维数组,其中有效的横坐标x与纵坐标y的范围都1≤x≤n,1≤y≤n。当从顶点v1到顶点v2的有向边存在时,a[v1][v2]用于记录有向边的权值,而无权图相当于所有有向边权值都相等(都等于1)的加权图,无向图则相当于有向边v1->v2与v2->v1同时存在的有向图。对于不存在的有向边(noEdge),通常记其权值为0或∞,本文均记为0。当有向图初始化时,所有原创 2020-12-06 21:24:05 · 3274 阅读 · 0 评论 -
[C++]索引二叉搜索树 插入、按关键字/按名次查找、按关键字/按名次删除
索引二叉搜索树是在二叉搜索树的基础上,给每个节点添加了一个leftSize属性,用于记录该节点左子树的节点个数。基于leftSize属性,搜索树可以按照名次快速找到该名次所对应的节点,从而扩展出了按名次查找节点和删除指定名次的节点的操作。名次查找读入所需查找的名次index(从0开始),先确定该名次是否超出范围。然后指针从根节点出发,循环操作,比较根节点的leftSize与index大小,若index更小,则指针指向左子树;若index更大,则指针指向右子树。每当指针前往右子树时,index都需要减去(原创 2020-12-02 09:51:03 · 1823 阅读 · 1 评论 -
[C++]搜索树 查找/插入/删除
搜索树:一种二叉树,满足任何节点的关键字大于都其左子树所有节点的关键字,小于其右子树所有节点的关键字(默认所有节点关键字不重复)。查找:输入需要查找的关键字,从根节点开始,通过比较关键字的大小来搜索,若查找关键字小于根节点,则考察左子树;若查找关键字大于根节点,则考察右子树。最终若指针指向空节点,说明查找元素不存在。插入:方法类似于查找,最终当指针指向的空节点即为插入元素的位置。删除:先找到需要删除的节点的位置,若不存在则返回。若删除节点有两个子树,则需要先将需要删除的节点的左子树最大值(或右子树的最原创 2020-11-29 22:43:55 · 427 阅读 · 0 评论 -
[C++]小根堆 插入/删除/初始化
小根堆的性质:是完全二叉树,根节点的关键字小于等于两个子节点的关键字。插入和删除操作都应当保证小根堆的性质不变。由于小根堆是完全二叉树,所以使用数组存放具有显著优势:按照层次遍历将具有n个元素的小根堆的存放到数组(命名为heap)的[1]~[n]项中。此时对于任一元素heap[i],其父节点为heap[i/2],其子节点为heap[i * 2] 和 heap[i*2+1]。1、插入元素:从新的叶节点开始,向上考察其父节点,若父节点的关键字大于新节点的关键字,则二者交换位置,然后继续向上考察;否则循环停原创 2020-11-25 17:21:55 · 2687 阅读 · 0 评论 -
[C++]二叉树 四种遍历/节点高度/子节点个数
基本操作1.遍历:前序遍历、中序遍历、后序遍历、层次遍历前三者使用递归实现、层次遍历使用队列实现2.计算某节点的高度:递归3.计算以某节点为根节点的二叉树的节点个数:递归代码#include<iostream>#include<queue>#include<vector>using namespace std;template<class T>struct binaryTreeNode//定义二叉树节点{ T element;//当前原创 2020-11-25 17:01:15 · 576 阅读 · 0 评论 -
[C++]散列表 线性开型寻址&链表散列
线性开型寻址由一维数组存放散列表,数组的每一项称为桶,不同的桶对应不同的关键字。向散列表中插入元素时,先按照元素的关键字找到关键字对应的桶,若桶为空,则将元素存入其中;若桶已被其他元素占用,则从该桶开始向后寻找空桶(将数组视为环形,即数组末项的后一项是数组首项),将元素存入找到的第一个空桶中,若找不到空桶,说明数组已满,插入失败。删除散列表元素时,先判断该元素是否存在,若不存在则无法删除。将该元素所在的桶清空,然后将其之后、下一个空桶之前所有受该桶影响被挤走的元素依次向前移动到空位。代码class原创 2020-11-25 16:40:17 · 666 阅读 · 0 评论 -
[C++]队列(数组描述)
将一维数组视作环形,即数组最后一项的下一项是数组首项。将队列中的元素按照顺序存入环形数组中,则只需记录队首和队尾的下标即可确定整个队列在数组中的位置。在该循环数组中,队尾插入(数组未满时)和队首删除的时间复杂度均为O(1)。代码//定义数组描述的循环队列template<class T>class arrayQueue{public: arrayQueue(int init=100)//初始化 { queueFront = 0; queueBack = -1; l原创 2020-11-23 20:29:34 · 512 阅读 · 0 评论 -
[C++]栈(数组描述)& 利用栈实现一位整数计算器
定义栈类template<class T>class arrayStack//自定义数组描述的栈类{public: arrayStack(int init=100)//栈初始化 { arrayLength = init; arr = new T[arrayLength]; stackTop = -1; } ~arrayStack() {delete[]arr;} bool empty()const {return stackTop == -1;} int s原创 2020-11-19 15:02:07 · 397 阅读 · 0 评论 -
[C++]稀疏矩阵(一维数组描述)
操作:重载赋值、输入、输出运算符;稀疏矩阵加法、乘法、转置。代码:#include<iostream>#include<vector>using namespace std;struct matrixTerm//定义矩阵元素{ int row; int col; int value; matrixTerm()//初始化 { row = 0; col = 0; value = 0; } matrixTerm& operator=(mat原创 2020-11-19 14:42:57 · 898 阅读 · 0 评论 -
[C++]通讯录(线性表的数组描述)
题目描述通讯录中每一个联系人的内容有:姓名、电话号码、班级、宿舍。由标准输入读入联系人信息,使用线性表中操作实现通讯录管理功能,包括:插入、删除、编辑、查找(按姓名查找);键盘输入一班级,输出通讯录中该班级中所有人的信息。代码#include<iostream>#include<string>using namespace std;struct student{ string name; string phone; int classroom; int room原创 2020-11-14 11:33:07 · 1235 阅读 · 0 评论 -
[C++]排序算法:名次/选择/冒泡/插入
#include<iostream>using namespace std;template<class T>class mySort//创建类,用于调用排序方法{public: mySort(T* a, int l) { array = a; length = l; } void printArray()//输出数组 { for (int i = 0; i < length; i++) { cout << array[i]原创 2020-11-14 11:21:13 · 596 阅读 · 0 评论