Prim最小生成树算法
算法介绍普利姆算法是一种图算法,用于构建最小生成树。最小生成树的顶点全部连通,即沿任意顶点出发,可以达到图的全部顶点,且其所有边的权值最小。
算法描述:
从最小生成树集合中选择边权值最小且不在生成树集合中的顶点加入最小生成树集合,重复上述操作直到全部的点加入最小生成树集合。
算法实现现有5个村落(编号为0-4)需要在各个村庄中修路,使各村庄联通,且代价最小。
这里我们使用邻接矩阵来表示上图
普利姆算法执行过程实现普利姆算法需要利用两个辅助数组lowcost和edge。
lowcost数组用于保存最小生成树集合到各顶点的距离,数组索引与顶点相关联。l例如owcost[3]表示最小生成树集合到顶点4的距离
如果数组中元素值为0则表示顶点存在于最小生成树集合,否则表示权值大小。
edge用于存储顶点的边关系,edge[1]=2表示与节点1与节点2相连。
12int lowcost[graph->vexnum];int edge[graph->vexnum];
执行过程:
选定一个节点加入最小生成树集合,初始化lowcost和edge数组
重复下面3的步骤, ...
图的遍历
图的遍历包括广度优先搜索和深度优先搜索。
广度优先搜索广度优先搜索类似于树的层次遍历,利用队列实现
队列结构设计:
12345typedef struct QueueNode{ struct AdjNode* node; /*顶点*/ struct QueueNode* next; struct QueueNode* pre;}QueueNode;
队列相关操作
123456789101112131415161718192021222324252627282930313233343536373839/*循环队列*/QueueNode* initQueue(){ QueueNode* Q=(QueueNode*)malloc(sizeof(QueueNode*)); Q->next=Q; Q->pre=Q; Q->node=NULL; return Q;}int isEmpty(QueueNode *Q){ if(Q->next==Q) ...
图的邻接表法表示
图的邻接矩阵表示法数据结构定义123456789typedef struct AdjNode { struct AdjNode* next;/*后继顶点*/ char vtxname; /*顶点名称*/}AdjNode;typedef struct Graph{ struct AdjNode* list[MAX_SIZE]; /*头节点列表*/ int vtxnum; /*顶点数*/}Graph;
图的操作12345678910111213141516171819202122232425/*初始化图*/struct Graph* initGraph();/*根据顶点名称找到顶点索引*/int findNodeIndex(Graph *graph,char vtxname);/*根据顶点名称找到顶点指针*/AdjNode *findNode(Graph *graph,char vtxname);/*在邻边链表中删除元素的辅助函数*/int deleteEdgeHelp(AdjNode* head,char vtx);/ ...
图的邻接矩阵表示
图是一种中一对多的数据类型。图的表示方法有邻接矩阵法,十字链表法。
图的操作包括
Adjacent(G,x,y):判断图G是否存在边<x,y>或(x,y)。
Neighbors(G,x):列出图G中与结点x邻接的边。
InsertVertex(G,x):在图G中插入顶点x。
DeleteVertex(G,x):从图G中删除顶点x。
AddEdge(G,x,y):若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边。
RemoveEdge(6,x,y):若无向边(x,y)或有向边<x,y>存在,则从图G中删除该边。
FirstNeighbor(G,x):求图G中顶点x的第一个邻接点,若有则返回顶点号。若x没有邻接点或图中不存在x,则返回-1。
邻接矩阵表示适合密集图
图的存储方式1234567#define MAX_SIZE 10typedef struct Graph{ int vexnum; /*节点个数*/ int vertices[MAX_SIZE]; /*节点数组*/ ...
哈夫曼树
哈夫曼树是一种带权路径最小的树,运用于压缩编码算法。
带权路径又称WPL,是所有非叶子节点的路径之和,路径=深度*权值
哈夫曼树的节点个数=2*带权节点个数-1
哈夫曼树的构造过程在未组成哈夫曼树的节点中寻找权值最小和第二小的节点,作为左右孩子,构造一个新节点作为父节点,父节点的权值为左右孩子的权值之和
哈夫曼树的表示哈夫曼树用顺序存储的数组表示。
存储结构如下
12345678910111213typedef struct TreeNode{ int weight; int parent; int lchild; int rchild;} TreeNode;typedef struct HaffTree{ struct TreeNode *node; int length;} HaffTree;
哈夫曼树的初始化操作123456789101112131415HaffTree *initTree(int *weight, int length){ HaffTree *T ...
linxu的main函数启动过程
main函数源码
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253/* * This is set up by the setup-routine at boot-time */#define EXT_MEM_K (*(unsigned short *)0x90002) /*扩展内存数,单位为KB*/#define DRIVE_INFO (*(struct drive_info *)0x90080)#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)void main(void) /* This really IS void, no error here. */{ /* The startup routine assumes (well, ...) this *//*hexhe * Interrupts are still disabled. Do necessary setup ...
树和森林
树的存储方式双亲表示法
存储方式双亲表示法使用数组实现
parent存放父亲在数组的索引
插入操作插入操作在数组末尾加入数据
孩子表示法使用顺序存储和链式存储实现
孩子兄弟表示法将下面的树使用孩子兄弟表示法,可以转化为
树 二叉树 森林的转化
操作符重载
操作符重载操作流重载cout是一种ostream类型
1234operator <<(ostream &os,const complex& x){ return os<<'C'<<real(x)<<','<<imag(x)<<')';}cout<<conj(c1)//调用函数operator <<(cout,c1)
thread
c11提供了线程的标准库
lamda表达式左值引用完美转发forward队列queueemplace可变参数模板函数万能引用右值引用函数适配器bind时间库chrono
线程库的使用1234567891011#include<iostream>#include<thread>void func(){ std::cout<<"线程启动"<<std::endl;}int main(){ std::thread th1(); return 0;}
lock_guardlock_guard是C++11提供的锁管理机制,能够对共享变量进行自动加锁和解锁。
初始化
1std::lock_guard<std::mutex> guard(mux);
源码:
123456789101112131415161718192021template<typename _Mutex> class lock_guard { public ...