数据结构和算法
Fantastic_HQ
厚积才能薄发。
展开
-
位于data[1:2^h-1]顺序存储的二叉树,用非递归算法建立二叉链表
算法思想使用层次遍历的思想,一层一层的建立,每次建立都是一层的元素全部建完,即每一层都是全部元素全部出队,下一层的元素全部入队,提醒:这里有个小坑要注意下,每次出队元素往右边移动时,对应i要记得相应加一,往右子树上挪动,这样计算的才是正确的该结点的下一层孩子结点,该题假设0为空结点,因为二叉树并非时完全二叉树,需要补充虚结点。#define MaxSize 20typedef struct BiTree{ struct BiTree* lchild; struct BiTree* .原创 2020-11-06 15:15:49 · 537 阅读 · 5 评论 -
给定一个二叉树, 找到该树中两个指定节点p和q(数值唯一)的最近公共祖先
寻找最近公共结点思想:判断p和q是否分别根结点的左右两侧,如果在左右两侧那么直接返回根结点即可,不失一般性,假设p和q分别均在根结点的左侧,那么按照分治的思想,此时继续往左子树找即可(问题规模已经缩小),那么依旧还是上面的操作划分,故可以采用递归的思想,后序遍历,如果在左子树找到了p,那么直接返回当前的root, 继续往root的右子树找,如果找到了q,说明root即是所找结点,如果未找到,将root返回给上一层继续搜索。typedef struct BiTree{ struct BiTre.原创 2020-11-05 14:19:52 · 1535 阅读 · 2 评论 -
将二叉链表的叶子结点按从左到右的顺序连成一个单链表,表头指针为head
简述:采用先序遍历,找到叶子结点,按照题目要求尾插法即可。typedef struct BiTree{ struct BiTree* lchild; struct BiTree* rchild; int data;}BiTree;BiTree* head;BiTree* pre;//pre指向前驱,目的主要是为了head始终指向头指针,使得head可以用于输出遍历。//要求该算法把二叉树的叶子结点按从左到右的顺序连成一个单链表,表头指针为headvoid leaves原创 2020-11-04 14:59:17 · 2300 阅读 · 0 评论 -
根据存储在数组[1...n]的先序序列pre和中序序列in建立二叉树
typedef struct BiTree{ struct BiTree* lchild; struct BiTree* rchild; int data;}BiTree;//根据先序和后序序列创建树//char pre[] ={'0','a','b','c','d','e','f','g','h','i'};//char in[] = {'0','b','c','a','e','d','g','h','f','i'};void PreInCreat(BiTree* &a原创 2020-11-03 16:20:18 · 503 阅读 · 0 评论 -
以孩子兄弟链表为存储结构,请设计非递归算法和递归算法求树的深度
这里简述孩子兄弟链表的非递归算法,如果A结点存在左孩子,且A结点的兄弟结点没有孩子,则该兄弟可以跳过不入队(因为A结点的兄弟结点树的高度不可能比A结点左孩子所在高度更高)typedef struct CsNode{ struct CsNode* firstchild; struct CsNode* nextsibling; int data;}CsNode;int height(CsNode* node){ //递归遍历求以孩子兄弟链表表示的树的深度 if (no.原创 2020-11-02 15:44:59 · 2927 阅读 · 0 评论 -
KMP模式匹配
void GetNext(char pattern[],int* &next,int length){ int i = 0; int j = -1; // pattern match next[0] = -1; while (i < length) { if (j == -1 || pattern[i] == pattern[j]) { i++; j++; next[i] =原创 2020-10-27 17:14:51 · 171 阅读 · 0 评论 -
选择排序算法(简单选择排序,堆排序)
//简单选择排序void selectSort(int data[],int num){ for (int i = 0; i < num-1; i++) { int min = i; for (int j = i + 1; j< num; j++) { if (data[j] < data[min]) { min = j; } } if.原创 2020-10-09 17:32:08 · 166 阅读 · 0 评论 -
交换排序算法(冒泡排序,快速排序)
int partition(int left,int right,int data[]){ int pivot = data[left]; while (left<right) { while (left<right && data[right]>=pivot) { right--; } data[left] = data[right]; .原创 2020-10-08 20:07:09 · 133 阅读 · 0 评论 -
插入排序算法(直接插入排序,希尔排序)
//49 38,65,97,76,13,27,49//38 49 65,97,76,13,27,49//38 49 65 97,76,13,27,49//38 49 65 97 76,13,27,49//38 49 65 76 97 13,27,49//13 38 49 65 76 97 27,49//13 27 38 49 65 76 97 49//13 27 38 49 49 65 76 97//插入排序: 插入第i个原创 2020-10-07 19:53:53 · 223 阅读 · 0 评论 -
二叉排序树查找/删除(附完整测试用例)
bool Delete(BTNode* &bt){ if (bt->left == NULL && bt->right == NULL) { BTNode* p = bt; bt = NULL; delete p; }else if(bt->left == NULL){ BTNode* p = bt; bt = bt->right; delete p原创 2020-09-24 20:47:31 · 428 阅读 · 0 评论 -
深度优先搜索DFS(非递归算法与递归算法)
DFS非递归算法借用栈记录当前状态,然后继续向下执行,等到一定的条件时再回来解决,下面给出实现代码。#include <iostream>#include <string>#include <vector>using namespace std;#define MaxSize 20typedef struct ArcNode{ struct ArcNode* next; int n;}ArcNode;typedef struct{原创 2020-09-22 16:29:06 · 884 阅读 · 0 评论 -
判断有向图是否存在经过v0的环的算法
判断是否存在环,可以使用拓扑排序以及使用DFS,BFS算法,此处我们采用DFS去实现,需要注意的情况是: 当v0有多个入度的时候,直接进行DFS也会误判成环,因此需要进行状态清除。bool DFSCircle(AGraph* G, int node, int* visit){ ArcNode* p; visit[node] = 1; p = G->arcList[node].fristNode; bool flag; while (p) { .原创 2020-09-21 17:27:21 · 393 阅读 · 0 评论 -
拓扑排序(AOV)
对一个有向无环图进行拓扑排序,过程如下:从有向图中选择一个没有前驱(即入度为0)的顶点,压入栈中删除栈中的顶点,同时删除该顶点出发的所有边(即顶点相邻边的顶点入度减一)重复以上两步,直至栈为空检查是否已经遍历图中所有结点,若全部遍历完成,则完成拓扑排序,反之,则该图存在环,拓扑排序失败。#include <iostream>#include <string>#include <vector>using namespace std;#define原创 2020-09-18 20:32:51 · 464 阅读 · 0 评论 -
多源最短路径(Floyd算法)
多源路径算法求解:对于单源最短路径,可以通过Dijkstra求解,那么多于多源最短路径是否可以利用Dijkstra求解呢?答案是显然的,我们可以通过遍历每个顶点进行Dijkstra求解,时间复杂度为O(n^3),由于Dijkstra算法编写较复杂,对于多源最短路径是否还有其他更简单的算法呢?另一种多源路径算法求解 — Floyd算法Floyd是通过动态规划的思想,我们定义f[k][i][j]表示i和j之间可以通过1,2,3,…k的结点的最短路径,从i到j可以有两种办法,一种是直接从i到j,另一种是借.原创 2020-09-18 18:44:20 · 1319 阅读 · 0 评论 -
单源最短路径(Dijkstra算法)
算法思想:Dijkstra算法和Prim算法思想相似,我们定义两个集合,走过的结点卫于集合S,未走过的结点卫于集合U中,在集合S中寻找是否有更短的路径能够到达未走过的结点,比如A–>B权值为2,B–>C权值5,A–C权值为10,A为起始点,那么一开始最短边为A–>B,那么我们把B加入集合中,当要去判断是否有更短的权值能够到达C,由于一开始A是起点,我们已经记录了A–>C的路径,要判断是否能更短的路径,只需在B点的基础上,判断能否有更短的路径到C,即判断A–>B + B–&g.原创 2020-09-16 16:17:08 · 5478 阅读 · 0 评论 -
最小生成树(Kruskal算法)
Kruskal算法思想Prim算法采用以顶点为起点,逐步进行查找顶点上最小权值的边来构建最小生成树,Kruskal算法采用以边为目标进行构建,因为权值在边上,所以直接根据最小权值的边进行构建生成树也是很自然的想法,只不过需要检测构建生成树时候产生环路。检测环路根据并查集的思想,通过判断被考察的边的两个顶点是否位于两个连通分量中,我们把连通分量看成树,通过判断两颗树是否有不同的根结点,如果是不同的根结点,那么不会产生环,进行合并,如果具有相同的根结点,那么产生环,则放弃该边,继续探索下一个更小权值的边。.原创 2020-09-15 16:45:19 · 287 阅读 · 0 评论 -
最小生成树(Prim算法)
采用Prim算法进行输出最小生成树,VNode数组记录有更小权值边连接的顶点,每次有结点加入集合中进行一次更新(检查新加入的元素对于之前元素是否有更小的权值到达未在集合中的顶点),lowCost记录最小权值,赋值为0是代表元素进入集合中。测试数据为:G->edges[0][1] = 34; G->edges[1][0] = 34;G->edges[0][2] = 46; G->edges[2][0] = 46;G->edges[0][5] = 19; G->原创 2020-09-14 17:07:10 · 245 阅读 · 0 评论 -
BFS 判断顶点i和顶点j是否有路径
从顶点i开始到顶点j进行一次BFS,遍历过程如果访问到了vj,则判定vi与vj存在路径。#define MaxSize 10typedef struct ArcNode{ struct ArcNode* next; int adjNum;}ArcNode;typedef struct{ ArcNode* firstArc; char data;}VNode;typedef struct{ VNode adjList[MaxSize]; in原创 2020-09-12 15:22:27 · 664 阅读 · 0 评论 -
BFS 求无向连通图距离顶点v最远的顶点
因为图的广度优先遍历方式是从图的某个顶点开始,由近至远层层拓展的方式遍历图结点的过程,因此图的广度优先遍历的最后一个结点一定是距离该顶点最远的一个结点。#define MaxSize 10//邻接表定义typedef struct ArcNode{ struct ArcNode* nextArc; int arcNum;}ArcNode;typedef struct{ ArcNode* fristArc; char data;}VNode;typedef原创 2020-09-11 17:24:14 · 2022 阅读 · 0 评论 -
图的广度优先遍历(BFS)
图的广度优先遍历类似于树的层次遍历,差异在于需要判断该顶点是否已经被访问。//邻接表typedef struct ArcNode{ int adjvex; struct ArcNode* nextArc;}ArcNode;typedef struct{ char data; ArcNode* firstArc;}VNode;typedef struct{ VNode adjList[MaxSize]; int n; int e;}A原创 2020-09-10 17:41:41 · 664 阅读 · 0 评论 -
图的深度优先遍历(DFS)
图的深度优先遍历类似于树的先序遍历,不同之处是为了避免重复访问,采用全局数组存储结点是否已经被访问的信息,对于邻接表而言,找邻接点所需的时间取决于顶点个树和边的个数,因此时间复杂度为o(n+e),如果把图的深度优先遍历过程说经历的边保留,把其余边删掉,那么会形成一颗树。#define MaxSize 5#define INF 100//邻接表typedef struct ArcNode{ int adjvex; struct ArcNode* nextArc;}ArcNode;原创 2020-09-10 17:00:16 · 817 阅读 · 0 评论 -
图 - 存储结构(邻接表)
由于邻接矩阵对于顶点较多,边较少时,但是存储边的二维矩阵是必须预先初始化的,所以会造成空间的浪费。因此可以采取通过链表和数组进行结合的方式(类似于孩子兄弟表示法),用数组存储顶点表,每个顶点记录指向该结点出度边的链头,通过链表存储该边的所有出度,采用头插法进行插入。#define MaxSize 5#define INF 100//邻接表typedef struct ArcNode{ struct ArcNode* next; int num;}ArcNode;typed.原创 2020-09-07 20:02:15 · 325 阅读 · 0 评论 -
图 - 存储结构(邻接矩阵)
对于边较于顶点数较多的图,使用邻接矩阵较于使用邻接表更能充分利用存储空间。邻接矩阵是由两部分组成,第一部分是顶点部分,由于顶点不分先后,主次,采用一维数组存储顶点表。第二部分是存储边表,边或弧存储的是边与边的关系,对于有向图而言,需要记录结点A指向B,亦或结点B指向A,那么考虑采用二维数组进行存储结点与结点之间的边表。typedef struct{ int n; char data;}Vertype;typedef struct{ int edges[MaxSi..原创 2020-09-07 19:09:32 · 272 阅读 · 0 评论 -
二叉树非递归后序遍历(手动维护栈及使用标志位记录是否已访问左右节点)
#define MaxSize 15typedef struct BTNode{ char data; struct BTNode* left; struct BTNode* right;}BTNode;typedef struct PoseNode{ BTNode* node; int visitRight; int visitLeft; PoseNode(){ this->visitLeft = 0;原创 2020-08-29 16:42:28 · 262 阅读 · 0 评论 -
中序遍历非递归(两种解法)
typedef struct BTNode{ char data; struct BTNode* left; struct BTNode* right;}BTNode;typedef struct Stack{ BTNode* data[MaxSize]; int top;}Stack;//中序遍历非递归void InOrder(BTNode* root){ if (root == NULL) { return; }原创 2020-08-28 16:29:16 · 888 阅读 · 0 评论 -
先序遍历非递归算法(手动维护栈)
void PreOrder(BTNode* root){ if (root == NULL) { return; } //Init Stack stack; stack.top = -1; //Root gets into stack BTNode* q; stack.top++; stack.data[stack.top] = root; //Process while (stack.top !.原创 2020-08-28 15:50:28 · 259 阅读 · 0 评论 -
计算二叉树宽度(BFS)
#define MaxSize 15typedef struct BTNode{ char data; struct BTNode* left; struct BTNode* right;}BTNode;//BFS 模板代码void level(BTNode* p){ int front,rear; BTNode* que[MaxSize]; front = rear = 0; BTNode* q; if (p != NULL) {原创 2020-08-27 19:13:34 · 671 阅读 · 0 评论 -
计算二叉链表存储的二叉树的深度(递归与非递归)
//输入先序遍历第K个节点的值void PreFind(BTNode* node,int k,int &count){ //recursion terminator if (node==NULL) { return; } if (k == count) { cout<<node->data<<"\n"; return; } //空不用进入 if (node->原创 2020-08-26 15:42:27 · 3784 阅读 · 2 评论 -
考研代码记录
void Enqueue(CircleNode* &circlelist,int data){ CircleNode* r = circlelist; CircleNode* newNode = (CircleNode*)malloc(sizeof(CircleNode)); newNode->data = data; newNode->next = r->next; r->next = newNode; }void De原创 2020-08-25 16:32:37 · 161 阅读 · 0 评论 -
Leetcode-15. 3Sum
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.Note:The solution set must not contain duplicate triplets.Example:Given array nums = [-1, 0原创 2020-07-23 16:02:13 · 128 阅读 · 0 评论 -
Chapter 4.1, Problem 1E Solution(Computer Organization and Design)
Step 1 of 2 Consider which shows the basic implementation of the MIPS subset, with all the functional units, necessary multiplexers, and control lines. As the figure suggests, the basic functional un...原创 2019-10-25 05:07:02 · 1908 阅读 · 0 评论 -
RSA加密算法
图为 RSA公开密钥算法的发明人,从左到右Ron Rivest, Adi Shamir, Leonard Adleman. 照片摄于1978年 RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新来的同事对它不太了解,恰好看到一本书中作者用实例对它进行了简化而生动的描述,使得高深的数学理论能够被容易地理解。我们经过整理和改写特别推荐给大家阅读,希望能够对时间紧...转载 2018-09-17 12:38:36 · 914 阅读 · 0 评论 -
链表的头插法和尾插法
void TailCreatList(List *L) //尾插法建立链表 { List *s, *r;//s用来指向新生成的节点。r始终指向L的终端节点。 r = L; //r指向了头节点,此时的头节点是终端节点。 for (int i = 0; i < 10; i++) { s = (struct List*) malloc(s...原创 2018-08-04 21:32:31 · 493 阅读 · 0 评论 -
中缀表达式转换成后缀表达式 -- 栈
为什么要转换后缀表达式严格按照从左到右进行计算的模式,符合计算机运行方式,而中缀表达式需要计算机遇到符号后向后扫描一位,若为括号或优先级更高的操作符还需要向后继续扫描。如何转换设我们欲将中缀表达式 a+b*c+(d*e+f)g转换成后缀表达式,正确的答案为:abc*+de*f+g*+转换步骤 当我们读入操作数的时候,立即将其放入到输出中,操作符不立即输出,将其放入栈中。如果我们见到一原创 2017-06-13 21:32:14 · 16976 阅读 · 5 评论 -
RSA私钥加密研究
RSA私钥加密研究 朋友碰到调用第三方API的加密问题,JAVA代码中用pfx私钥文件来加密字符串,流程如下: 输入私钥文件地址pfxPath、私钥密码pfxKey、被加密串dataContentdataContent转成base64串,使用sun.misc.BASE64Decoder包用pfx私钥及PKCS12方式生转载 2017-06-21 16:57:37 · 745 阅读 · 1 评论 -
一致性哈希算法
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:1、平衡性(Balance):平衡转载 2017-05-22 18:11:16 · 468 阅读 · 0 评论 -
二维数组的查找
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。//题目思考: 从哪里进行判断比较比较适合,经分析,左下角和右上角进行判断都是可行的办法.为什么不从左上角开始搜寻呢?因为左上角向右和向下都是递增,那么对于一个点,对于向右和向下会产生一个岔路;如果我们选择从左下脚开始搜寻的话,如原创 2017-04-28 18:10:46 · 501 阅读 · 0 评论