数据结构
ChanJose
这个作者很懒,什么都没留下…
展开
-
C++ 求所有顶点之间的最短路径(用Dijkstra算法)
一、思路: 不能出现负权值的边 (1)轮流以每一个顶点为源点,重复执行Dijkstra算法n次,就可以求得每一对顶点之间的最短路径及最短路径长度,总的执行时间为O(n的3次方)(2)另一种方法:用Floyd算法,总的执行时间为O(n的3次方)(另一文章会写)二、实现程序: 1.Graph.h:有向图#ifndef Graph_h#define Gr...原创 2019-03-28 23:29:02 · 2250 阅读 · 2 评论 -
C++ 最小生成树之Prim算法
一、思路: 和Kruscal类似,先从一个顶点u出发,找u的邻接顶点v,如果(u,v)权值最小且v顶点不在生成树顶点集合中(防止出现回路),则把边(u,v)存到最小生成树中;否则该顶点已经在生成树顶点集合中,舍弃该边,找权值次小的另一条边。然后,从顶点v出发,找下一条不会出现回路的边(v,w)。直到找到n-1条边。 1.假如从顶点A出发,找A的邻接顶点(不在生成树顶...原创 2019-03-25 19:43:25 · 3183 阅读 · 0 评论 -
C++ AVL树(高度平衡的二叉搜索树)
一、思路 1.创建AVL树: 每次输入一个数num,然后用Insert()函数,将num插入到AVL树中。// 创建AVL平衡树template <class T>void AVLTree<T>::CreateAVLTree() { T num; cout << "请输入数(以-1结束输入)建立平衡二叉树...原创 2019-03-25 13:05:18 · 627 阅读 · 3 评论 -
C++ 最小生成树之kruskal(克鲁斯卡尔)算法
一、思路: 总共选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。 意思就是:n个顶点,要取n-1条边,形成连通分量。每一次取权值最小的一条边,如果不形成回路就添加到最小生成树中;否则,舍弃这条边,取权值次小的边,重复前面步骤,直到取了n-1条边和所有顶结点被访问过。最小生成树:minimum-cost ...原创 2019-03-25 00:05:24 · 1494 阅读 · 0 评论 -
C++ 哈夫曼树(HuffmanTree)
如何建立哈夫曼树的,网上搜索一堆,这里就不写了,直接给代码。1.哈夫曼树结点类:HuffmanNode.h#ifndef HuffmanNode_h#define HuffmanNode_htemplate <class T>struct HuffmanNode { T weight; // 存储权值 HuffmanNode<T> *lef...原创 2019-03-12 19:48:57 · 2559 阅读 · 0 评论 -
C++ 图的深度优先搜索(DFS)和广度优先搜索(BFS)
一、图的深度优先搜索和广度优先搜索 1.图的深度优先搜索: 类似树的前序遍历 2.图的广度优先搜索: 类似树的层次遍历二、实现程序:1.Graphlnk.h#ifndef Graphlnk_h#define Graphlnk_h#include <iostream>#include <queu...原创 2019-03-20 20:14:37 · 1469 阅读 · 0 评论 -
C++ 图的邻接表表示
一、实现程序:1.Graphlnk.h#ifndef Graphlnk_h#define Graphlnk_h#include <iostream>using namespace std;const int DefaultVertices = 30;template <class T, class E>struct Edge { // 边结点的定...原创 2019-03-20 18:38:04 · 1167 阅读 · 1 评论 -
C++ 线索二叉树
TreadTree.h#ifndef TreadTree_h#define TreadTree_h#include <iostream>#include <stack>using namespace std;/*ltag = 0 //lchild指向节点的左孩子ltag = 1 //lchild指向节点的前驱节点rtag = 0 //rchild指...原创 2019-03-12 11:48:06 · 621 阅读 · 0 评论 -
C++ 图的邻接矩阵表示
1.遇到的问题:教材中写着子类Graphmtx(我用GrapMatrix)继承基类Graph 但是我在子类GraphMatrix中使用父类Graph的保护成员属性:maxVertices 显示没有声明(如下图)。 原来,c++中声明一个模板类及子类,在子类中如果需要访问父类的protected变量,需要使用父类的类作用域限定符,否则会报“identifier...原创 2019-03-20 13:19:09 · 2182 阅读 · 1 评论 -
C++ 最大堆
#include <iostream>#include <stack>const int DefaultSize = 100;template <class T>class MaxHeap{public: MaxHeap(int sz = DefaultSize); MaxHeap(T arr[], int n); ~Ma...原创 2019-03-14 12:53:17 · 2175 阅读 · 1 评论 -
C++ 最小堆
// 对最小堆的各种操作// 最小堆:完全二叉树,可以采用顺序存储结构#include <iostream>#include <stack>const int DefaultSize = 100;template <class T>class MinHeap{public: MinHeap(int sz = DefaultSiz...原创 2019-03-14 12:52:23 · 1654 阅读 · 0 评论 -
C++ 广义表转二叉树,二叉树转广义表
#include <iostream>#include <stack>struct BinTreeNode { char data; BinTreeNode *leftChild; BinTreeNode *rightChild;};// 前序遍历二叉树void PreOrder(BinTreeNode *p) { if(p ...原创 2019-03-14 12:50:56 · 1146 阅读 · 1 评论 -
C++ 二叉搜索树(Binary Search Tree)
// 二叉搜索树:// A.每个结点都有一个关键码,每个关键码互不相同;// B.左子树(若存在)上所有结点的关键码都小于根结点的关键码;// C.右子树(若存在)上所有结点的关键码都大于根结点的关键码;// D.左子树和右子树也是二叉搜索树//// 建立:采取插入建立// 遍历:采取中序遍历//// 测试数据:53 78 65 17 87 09 81 15 -...原创 2019-03-14 12:46:56 · 387 阅读 · 0 评论 -
C++ AOE网络
一、思路(你可以用拓扑排序来做,但我这里没用拓扑排序) (1)求事件Vi的最早可能开始时间是从源点V0到顶点Vi的最长路径长度。 如V0=0, V1=6,V2=4,V3=5;V4事件要等V1和V2事件完成后才可以进行,所以要取事件用的最长的时间,即V4=6+1=7,同样道理得出其他时间。 (2)事件Vi的最迟允许开始时间Vl[i]是在保证汇点Vn...原创 2019-04-03 22:19:52 · 1131 阅读 · 0 评论 -
C++ 选择排序(selectionSort)
一、思路 每次取剩下没排序的数中的最小数,然后,填到对应位置。(可以使用a[0]位置作为暂存单元) 如下: 二、实现程序:#include <iostream>using namespace std;const int maxSize = 100;template<class T>void Sele...原创 2019-04-03 23:00:00 · 335 阅读 · 0 评论 -
C++ 桶排序(BucketSort)
一、思路 是将[0,1]区间划分为n个等长的子区间。然后,将各个元素按照自己所属的区间放入相应的桶中,只需要将每个桶的元素排好序,依次输出各个桶内的元素,就得到了有序的元素序列。二、实现程序:#include <iostream>using namespace std;const int offset = 105; // 为桶的边界const int ...原创 2019-04-08 08:28:45 · 11209 阅读 · 4 评论 -
C++ 归并排序(MergeSort)
一、思路:稳定排序 (1)划分:一直调用划分过程,直到子序列为空或只有一个元素为止,共需log2(n); (2)归并:将两个子序列从小到大合并为一个序列二、实现程序:// 归并排序:(二路归并)// (1)递归分解数组;// (2)合并有序的序列#include <iostream>using namespace std;// 合并两...原创 2019-04-08 08:25:44 · 699 阅读 · 0 评论 -
C++ 冒泡排序(BubbleSort)
一、思路:冒泡排序算法原理:1.比较相邻的元素。如果第一个数比第二个数大,就交换他们两个。2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。3.针对所有的元素重复以上的步骤,除了最后一个。(因为最后一个已经排好,是最大的数)4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。(接着排第二大的数,一直下去)...原创 2019-04-08 08:23:16 · 3178 阅读 · 0 评论 -
C++ 希尔排序(ShellSort)
一、思路: 希尔排序:又称缩小增量排序,是一种改进的插入排序算法,是不稳定的。 设排序元素序列有n个元素,首先取一个整数gap<n作为间隔,将全部元素分为gap个子序列,所有距离为gap的元素放在同一个子序列中,在每一个子序列中分别施行直接插入排序。然后缩小间隔gap,重复上述的子序列和排序工作。二、实现程序:#include <iostre...原创 2019-04-08 08:18:58 · 391 阅读 · 0 评论 -
C++ 折半插入排序(BinaryInsertSort)
一、思路: 较插入排序,减少了比较的次数,但是插入时间还是一样。 (1)按二分查找的方法,查找V[i]在V[0],V[1]…V[i-1]中插入的位置; (2)将插入位置的元素向后顺移。二、实现程序:// 二分插入:较插入排序,减少了比较的次数,但是插入时间还是一样// 时间复杂度还是:O(n*n)#include <iostream&g...原创 2019-04-08 08:15:53 · 534 阅读 · 0 评论 -
C++ 直接插入排序(InsertSort)
一、思路 当插入第i(i>=1)个元素时,前面的V[0], V[1], …,V[i-1]已经排好序。 用V[i]的排序码与V[i-1],V[i-2],…,的排序码顺序进行比较,找到插入位置。然后,将V[i]插入,原来位置上的元素向后顺移。二、实现程序:#include <iostream>using namespace std;const...原创 2019-04-08 08:13:45 · 4632 阅读 · 0 评论 -
C++ 任意权值的单源最短路径(Bellman-Ford)
一、有Dijkstra算法求最短路径了,为什么还要用Bellman-Ford算法 Dijkstra算法不适合用于带有负权值的有向图。 如下图: 用Dijkstra算法求顶点0到各个顶点的最短路径: (1)首先,把顶点0添加到已访问顶点集合S中,选取权值最小的邻边<0, 2>,权值为5 记录顶...原创 2019-03-28 20:06:11 · 1194 阅读 · 1 评论 -
C++ 拓扑排序(AOV网络)
一、思路 先扫描所有顶点,把入度为0的顶点(如C,E)进栈。然后,取栈顶元素,退栈,输出取得的栈顶元素v(即入度为0的顶点v)。接着,把顶点v的邻接顶点w的入度减1,如果w的入度变为0,则进栈。接着,取顶点w的兄弟结点(即取顶点v的邻接顶点w的下一邻接顶点),做同样的操作。重复上面步骤,直到输出n个顶点。如上图:(1)扫描所有顶点,把入度为0的顶点进栈:将顶...原创 2019-04-01 21:13:45 · 988 阅读 · 0 评论 -
C++ 有向图最短路径之Dijkstra算法
一、思路 1.Dijkstra算法 每次都是从起始顶点v出发,找与v有关的有向边<v,u>。找到<v, u>之后,找有向边<u,k>,如果通过绕过顶点u而使从v到k的路径更短的话,就要修改v到k的路径。即v->u>k的路径比v->k的路径更短。 如上面的有向图:起始顶点为0 (1)先将顶点...原创 2019-03-26 22:01:42 · 8671 阅读 · 5 评论 -
C++ 有向图的邻接表表示
一、思路: 有向图的插入有向边、删除边、删除顶点和无向图的有区别。其他的和无向图的类似。 1.插入有向边<e1, e2> 只需要插入<e1, e2>边就行,不需要插入对称边<e2, e1> 2.删除边<e1,e2>: 只需要删除<e1, e2>边...原创 2019-03-26 19:56:22 · 4220 阅读 · 0 评论 -
C++ 所有顶点之间的最短路径(用Floyd算法)
一、思路: 不能出现负权值的边 用Floyd算法,总的执行时间为O(n的3次方) k从顶点0一直到顶点n-1, 如果,有顶点i到顶点j之间绕过k,使得两顶点间的路径更短,即dist[i][k] + dist[k][j] < dist[i][j],则修改:dist[i][j] 如:(1)当k=0时, 顶点2...原创 2019-03-30 16:25:10 · 1149 阅读 · 0 评论 -
C++ 堆排序(HeapSort)
一、思路:(1)将数组arr[0~n-1]调整形成最大堆; (2)取堆顶点(即取最大值)放到数组arr[n-1]的位置,即将arr[0]与arr[n-1]交换位置; (3)调整arr[0]到arr[n-2]重新形成最大堆; (4)同理,取堆顶arr[0](即取最大值)放到数组arr[n-2]位置,即交换arr[0]与arr[n-2]位置; (5)重复以上步...原创 2019-04-03 23:39:02 · 661 阅读 · 0 评论 -
C++ 并查集2(带路径压缩)
一、实现程序:#include <iostream>using namespace std;struct Node { // 并查集结点类 int data; // 保存数据 int parent; // 保存父结点};class UnionFindSets {public: UnionFindSets(int w[], int n); //...原创 2019-03-14 11:22:58 · 367 阅读 · 0 评论 -
C++ 并查集(Union-Find Sets)
一、实现程序:#include <iostream>using namespace std;struct Node { // 并查集结点类 int data; // 保存数据 int parent; // 保存父结点};class UnionFindSets {public: UnionFindSets(int w[], int n); //...原创 2019-03-14 10:15:47 · 441 阅读 · 0 评论 -
C++ 哈夫曼编码
1.哈夫曼编码的结点类:struct HuffmanNode { int weight; // 权重,出现的次数或者频率 char ch; // 存储符号 string code; // 存储该符号对应的编码 int leftChild, rightChild, parent; // 左、右孩子,父结点};2.思路:(1)统计输入的字符串中不同字...原创 2019-03-13 23:51:26 · 22447 阅读 · 10 评论 -
C++ 静态链表
一、动态链表和静态链表区别: (1)动态链表: (2)静态链表: 应用:二叉树 二、思路: 1.结点设置:T data; int link; 2.链表要用一个avil来保存可分配空间的首地址; 3.初始化:引入头结点:elem[0]; ...原创 2019-01-07 11:40:08 · 689 阅读 · 0 评论 -
C++ 汉诺塔问题(递归)
一、思路: if(n == 1) { 直接从A移到C柱子上; } if(n > 1) { 先把A柱子上的前n-1个盘子(看作一个整体)从A借助C移到B; 接着将A柱子上的第n个盘子直接移动到C柱子上; 再将B柱子上的n-1个盘子借助A移动到C...原创 2019-01-11 21:51:46 · 5131 阅读 · 1 评论 -
C++ 高精度减法运算(a=a-b)
一、题目 求两个大的正整数相减的差。 二、思路 1.接收输入的两个大整数的数字串: 用string接收两个正整数的数字串(C用字符数组或字符指针); 2.比较两个正整数哪个大? (1)比较两个大整数的数字串长度; (2)如果长度相等,可用strcmp函数比较两个数字串,头文件为:#include <...原创 2019-01-17 10:20:32 · 2345 阅读 · 1 评论 -
C++ 约瑟夫(Josephus)问题
一、题目:约瑟夫问题:n个人围成一桌,数到m的人出列 二、实现方法1: 每出列一个,就往前移动数组,用求余解决到尾问题// 每出列一个,就往前移动数组// 用求余解决到尾问题#include <iostream>void JosePhus(int n, int m, int start) { int i, *arr = new int[n]; // 动态分...原创 2018-12-31 23:13:00 · 5966 阅读 · 0 评论 -
C++ 快速排序(Quicksort)算法
一、基本思想是: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。二、方法1实现程序:左右两个方向扫描// 快速排序:选第一个对象作为基准,按照该对象的排序码大小,将整个对象// 序列划分为左右两...原创 2018-12-31 22:21:30 · 2192 阅读 · 0 评论 -
C++ 双向冒泡排序算法(Shaker Sort)
一、概念(来源于百度百科) 传统冒泡算法原理 冒泡排序算法的运作如下:(从后往前) 1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 3.针对所有的元素重复以上...原创 2018-12-31 21:55:48 · 3234 阅读 · 0 评论 -
C++ 将序列前半部分为负整数,后半部分为正整数(数据分类)
一、题目: 将序列前半部分为负整数,后半部分为正整数,不要求排序,但要求尽量减少交换次数。 二、思路: 首先,从数组0开始往后找第一个正整数位置pos;然后,从数组len-1开始往前找第一个负整数位置neg; 接着,交换这两个数。pos往后找,neg往前找。重复前面步骤,直到pos>=neg结束。 三、实现程序#include <...原创 2018-12-31 21:50:13 · 351 阅读 · 0 评论 -
C++ 二分查找(折半查找、Binary Search)算法
思路:首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功; 否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一 子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为 止,此时查...原创 2018-12-31 21:17:07 · 1194 阅读 · 0 评论 -
C++ 链表的基本操作:头插入、尾插入、遍历、判断链表是否为空、清空、求长度、插入、删除、逆置链表和排序
//// main.cpp// List:// 链表的操作:// 1.头插入// 2.尾插入建立链表;// 3.遍历链表;// 4.链表是否为空// 5.清空链表// 6.求链表的长度// 7.排序// 8.插入结点// 9.删除结点:记得要释放删除节点的存储空间,避免内存泄漏// 1...原创 2018-12-31 15:16:50 · 1270 阅读 · 5 评论 -
C++ 中缀表达式转后缀表达式
一、思路:和中缀表达式的计算类似,只不过不用计算,把表达式输出即可 1.用字符数组存储整行输入的中缀表达式; 2.接着从字符数组的0位置开始判断字符,如果是数字,那就要判断后面是否是数字,如果是就不断扫描组成一个整数 (暂不考虑负数和小数),最终组成一个整数,然后输出这个数(因为不用计算,所以直接输出即可); 3.如果是左括号,直接进符号...原创 2019-01-03 23:44:47 · 14800 阅读 · 7 评论