数据结构
ShirleyPaul
这个作者很懒,什么都没留下…
展开
-
链表
#include<iostream>using namespace std;class Node {public: int data; Node* next; Node(int _data) { data = _data; next = NULL; }};class LinkList {private: Node*原创 2016-05-25 21:29:25 · 278 阅读 · 0 评论 -
深度优先搜索
深度优先搜索的优先遍历深度更大的顶点,所以我们可以借助栈这一数据结构来实现:1 将要访问的第一个顶点 v 入栈,然后首先对其进行访问;2 将顶点 v 出栈,依次将与顶点 v 相邻且未被访问的顶点 c 压入栈中;3 重复第一步操作,直至栈为空。#include <iostream>#include <vector>#include <cstring>using namespace std;cla原创 2016-05-31 23:13:41 · 238 阅读 · 0 评论 -
bfs广度优先搜索
这一课我们来学习图的另一种遍历方法——广度优先搜索(Breadth-First-Search,简称 BFS)。这是一种连通图的常用遍历策略,通常用于求起点到各点的最短路径,以及求两点之间的最优路径等问题。首先我们先来看看广度优先搜索的具体方法吧:对于一个连通图,我们假设一开始所有顶点均未被访问,广度优先搜索的主要操作如下:1 选择图中任意一个顶点 v 作为起点进行访问,并将顶点 v 标为已访问。2原创 2016-06-01 00:06:00 · 311 阅读 · 0 评论 -
堆排序
#include<iostream>using namespace std;class Heap {private: int *data, size;public: Heap(int length_input) { data = new int[length_input]; size = 0; } ~Heap() {原创 2016-06-01 09:13:02 · 215 阅读 · 0 评论 -
小顶堆_优先队列 ,实现哈夫曼树的WPL求值
优先队列内部一般是用堆来实现的。我们知道堆的插入、删除操作的时间复杂度都是 O(logN)O(logN),自然优先队列的插入、删除操作的时间复杂度也都是 O(logN)O(logN)。堆中的堆顶元素就是优先队列的队首元素。对于大根堆实现的优先队列,总是优先级高的元素先被删除;相对的,对于小根堆实现的优先队列,总是优先级低的元素先被删除。对于后者,我们也称之为优先队列。优先队列可以用于解决哈夫曼编码问原创 2016-06-01 15:14:13 · 1454 阅读 · 0 评论 -
并查集_森林_含秩的判断和路径优化
注意,不同教材在介绍森林的遍历方法时会有不同的表述,有些教材会将后序遍历称为中序遍历,但实质上遍历方法是一样的。森林的先序遍历的规则:访问森林中第一棵树的根结点 先序遍历森林中第一棵树的子树森林 先序遍历森林中,除第一棵树外其余树构成的森林 森林的后序遍历的规则:后序遍历森林中第一棵树的根结点的各子树所构成的森林 访问森林中第一棵树的根结点 后序遍历森林中除第一棵树外其余树构成的森林二叉树原创 2016-06-01 18:29:07 · 594 阅读 · 0 评论 -
连通图_连通分量FloodFill
首先,我们来介绍一个概念:子图(subgraph)。若一个图的顶点集和边集分别是另一图的顶点集的子集和边集的子集,则称该图为另一图的子图。换句话说,从一个图里选出一部分顶点和边,只要确保选择的边对应的两个顶点也都被选择,那么所有选出的顶点和边组成的图就是原图的子图。就像在一个社交网络中,同班同学的帐号之间的关系就组成了整个社交网络的一个子图。接下来,我们介绍一个概念:连通。在无向图中,如果有从顶点原创 2016-06-01 19:12:43 · 472 阅读 · 0 评论 -
最小生成树_Prim
如何从一个带权图中抽出一棵生成树,使得边权值和最小,这棵生成树就叫做最小生成树。常见的求解最小生成树的算法有 Prim 算法和 Kruskal 算法。我们先来学习 Prim 算法。首先我们定义带权图 G的顶点集合为 V,接着我们再定义最小生成树的顶点集合为 U,初始集合 U 为空。接着执行以下操作:首先我们任选一个顶点 x,加入集合 U,并记录每个顶点到当前最小生成树的最短距离。选择一个距离当前最小原创 2016-06-01 21:24:12 · 399 阅读 · 0 评论 -
Kruskal 最小生成树 & Dijkstra 最短路径
最小生成树的另一种算法——Kruskal 算法。首先我们定义带权图 G 的边集合为 E,接着我们再定义最小生成树的边集合为 T,初始集合 T 都为空。接着执行以下操作:首先,我们把图 G 看成一个有 n 棵树的森林,图上每个顶点对应一棵树。接着,我们将边集合 E 的每条边,按权值从小到大进行排序,依次遍历每条边 e = (u, v),我们记顶点 u 所在的树为 Tu ,顶点 v所在的树为 T原创 2016-06-01 21:53:19 · 622 阅读 · 0 评论 -
动态规划_最长上升子序列LIS
最长上升最序列Longest Increasing Subsequence 动态规划解决的经典问题 子序列不等于子串,子串一定是自序列,但子序列不一定是子串 因为子串必须连续将该题分解为n个子问题: 求解最后一个元素为原数组第i个元素的最长上升子序列 的长度#include <iostream>#include <cstdio>using namespace std;int n, dp原创 2016-07-09 21:27:31 · 234 阅读 · 0 评论 -
判断单链表是否含环
原文链接 http://www.cnblogs.com/shuaiwhu/archive/2012/05/03/2480509.html如图,如果单链表有环,则在遍历时,在通过6之后,会重新回到3,那么我们可以在遍历时使用两个指针,看两个指针是否相等。方法一:使用p、q两个指针,p总是向前走,但q每次都从头开始走,对于每个节点,看p走的步数是否和q一样。如图,当p从6走到3时,用了6步,此时若q从转载 2016-07-10 21:18:14 · 285 阅读 · 0 评论 -
查找(search)
查找(search) 是指在数据集合中寻找满足某种条件的数据元素的过程。用于查找的数据集合则称为 查找表(search table)。查找表中的数据元素类型是一致的,并且有能够唯一标识出元素的 关键字(keyword)。如果从查找表中找出了关键字等于某个给定值的数据元素,则称为 查找成功,否则称 查找不成功。通常对查找表有 4 种操作:查找:在查找表中查看某个特定的记录是否存在检索:查找某个特定记录原创 2016-07-03 23:41:35 · 1106 阅读 · 0 评论 -
排序(sorting)
什么是 排序(sorting) 算法?原创 2016-07-04 11:04:41 · 1747 阅读 · 0 评论 -
循环双端队列示例C++_通话列表的保存
#include <iostream>#include <cstdio>#include <queue>using namespace std;const int LEN = 10;// 自定义循环队列类,来实现题目要求的某一类// 在程序中调用定义举例如下:// circular_queue Q;// 如果要定义数组,比如这道题需要定义一个长度为3的循环队列数组,则参考如下定义:原创 2016-07-07 17:08:19 · 384 阅读 · 0 评论 -
冗余关系的判断_递归
线段树,听名字就能猜到啦,就是一颗每个节点都是线段的树。具体来说,这是一颗平衡二叉树,它的每个节点都是一个区间。就像下面这张图:我们处理线段树的时候需要用递归实现,线段树可以实现单点更新(比如修改区间上某个点的值)、区间更新(比如将某段区间的值统一加x)、单点查询(查询某个点的当前值)和区间查询(查询某段区间的所有点值的和),并且都是O(logN)的时间复杂度,是程序设计竞赛中非常常用的数据结构。冗原创 2016-07-09 11:57:02 · 1987 阅读 · 0 评论 -
堆_priority_queue_大顶堆
#include <iostream>#include <cstdio>#include <queue>using namespace std;priority_queue<int> myHeap;int main() { int n = 5, num[5] = {1, 3, 2, 5, 4}; // 在下面的循环内读入元素并插入堆 for (int i = 0; i原创 2016-07-09 15:55:04 · 273 阅读 · 0 评论 -
分治_递归_quick_sort
#include <cstdio>#include <iostream>using namespace std;void quick_sort(int dat[], int l, int r) { // 首先请填写下面三个变量的初值 int i = l, j = r, mid =dat[r] ; do { while (dat[i] < mid) ++i原创 2016-07-09 15:56:43 · 214 阅读 · 0 评论 -
图的基本知识及实现_邻接矩阵_邻接表
对于有 nn 个顶点的图 G = (V, E)来说,我们可以用一个 n * n的矩阵 AA来表示 G中各顶点的相邻关系,如果 v_{i}和 v_{j}之间存在边(或弧),则 A[i][j] = 1, 否则 A[i][j] = 0。 下图为有向图 G_{1}G1 以及对应的邻接矩阵。下图为无向图 G_{2}G2 以及对应的邻接矩阵。图的邻接矩阵是唯一的,矩阵的大小只与顶点个原创 2016-05-30 14:17:24 · 1405 阅读 · 1 评论 -
SBTree的左旋右旋以及各种调整操作的基本实现(包含查找第k大的数值)
在完成了左旋和右旋操作之后,我们要实现调用两种单旋操作的逻辑,也就是调整操作。在插入之后,一共有 44 种触发旋转的情况,分别为 LL 型、LR 型、RR 型和 RL 型。通过旋转的名称,可以很直观的想到其对应的不平衡的情况——比如 LR 型,就意味着左子树(L)的右子树(R)的元素个数过大。还记得我们之前讲到过的,SBTree 的平衡条件么?一共有两个:a: size[right[t]] ≥ ma原创 2016-05-30 12:37:38 · 550 阅读 · 1 评论 -
AVL_SBTree _基本原理
所有平衡树基本由以下三个特征组成:自平衡条件 旋转操作 旋转的触发 平衡树通过设置合理的自平衡条件,使得二叉排序树的查找、插入等操作的性能不至于退化到 O(n)O(n),并且在进行二叉排序树的查找、插入等操作时进行判断,如果满足其中某个旋转的触发条件,则进行对应的旋转操作。AVL 树是最早发明的一种平衡树。AVL 树的名称来源于它的两个发明者:G.M. Adelson-Velsky 和 E.M原创 2016-05-30 10:50:37 · 515 阅读 · 0 评论 -
约瑟夫环_循环链表实现
输入n,m; n个人,每次第m个人出列#include<iostream>using namespace std;class Node {public: int data; Node* next; Node(int _data) { data = _data; next = NULL; }};class LinkList {原创 2016-05-25 23:46:18 · 333 阅读 · 0 评论 -
哪位同学最优秀
每份简历都有一个对应的 id,编号从 1 开始,依次从第一份简历到最后一份简历。boss 会从简历里抽掉 M 份简历,每次他会念一个他认为不够吉利的数字 numi,然后从第一份简历开始数,数到第 numi 份时,就会把对应的简历抽调,接着念下一个数字。抽掉 M 份简历后,boss 从剩余的简历中,取出最中间的一份简历,然后点点头念道:“我相信这位同学一定最优秀,哈哈”。现在蒜头君想知道这份简历的 i原创 2016-05-26 21:28:07 · 1031 阅读 · 0 评论 -
队列的基本实现
队列的基本实现TIP:宏断言assert(<表达式>); 利用宏断言,如果不满足则说明队列空,直接返回;#include <iostream>#include <cassert>using namespace std;class Queue {private: int *data; int head, tail, length;public: Qu原创 2016-05-26 22:07:14 · 340 阅读 · 0 评论 -
循环队列基本实现
循环队列的基本实现#include <iostream>#include <cassert>using namespace std;class Queue {private: int *data; int head, tail, length, count;public: Queue(int length_input) { data = new in原创 2016-05-26 22:30:33 · 304 阅读 · 0 评论 -
栈的基本操作
栈的基本操作注:利用模板类建类,进行栈定义 模板类定义在整个类定义之前#include<iostream>#include<string>#include<cassert>using namespace std;template<class Type> class Stack {private: Type *urls; int max_size, top_index;p原创 2016-05-27 01:25:20 · 260 阅读 · 0 评论 -
栈_数列反转
栈_数列反转#include<iostream>#include<string>#include<cassert>using namespace std;template<class Type> class Stack {private: Type *urls; int max_size, top_index;public: Stack(int length_in原创 2016-05-27 01:34:04 · 455 阅读 · 0 评论 -
栈_极简单表达式运算
栈_极简单表达式运算极简单表达式运算: 运算符只有*,+ 表达式中只有数字和运算符 数字只有一位#include<iostream>#include<string>#include<cassert>using namespace std;template<class Type> class Stack {private: Type *urls; int max_siz原创 2016-05-27 01:59:57 · 328 阅读 · 0 评论 -
顺序表_循环左移
顺序表的构造、插入、扩展、查找、删除、遍历这 6 种操作。一种新的操作:循环左移。原创 2016-05-25 18:08:01 · 2054 阅读 · 0 评论 -
栈_火车调度
#include <iostream>#include<vector>#include<stack>using namespace std;void schedule(vector<int> &a, stack<int> &b, vector<int> &c, int sizec, int starta, int &n){if(sizec == a.size())//完成一种调度,输出调转载 2016-05-28 00:14:06 · 903 阅读 · 0 评论 -
栈_火车调度
一个火车调度站的容量为n,若入站口有编号为1、2、…、n的n节车厢,编写算法输出n节车厢的所有出站序列。用回溯法设计该问题的递归算法, 调度站当前状态下,只有两种操作: (1)若入站口车厢非空,则将入站口的k号车厢入栈,进入下一个状态继续试探(递归调用); (2)若调度站非空,则将栈顶车厢出栈进入出站序列,进入下一个状态继续试探(递归调用);#include <iostream>#inclu转载 2016-05-28 00:29:34 · 1364 阅读 · 0 评论 -
哈希表简介_基本操作
哈希表又叫散列表,关键值通过哈希函数映射到数组上,查找时通过关键值直接访问数组。在上面的例子里,我们将用户名通过哈希函数映射成一个整数,也就是数组的存储位置,在检测时用同样方法计算出存储位置,如果位置上已有元素则表示用户名已经被注册。哈希函数指的是关键值和存储位置建立的对应关系,查找时只要根据这个关系就能找到目标位置。一般我们只要通过一次查找就能找到目标位置,但有些关键字需要多次比较和查找才能找到,原创 2016-05-28 17:07:53 · 734 阅读 · 0 评论 -
哈希表_判断输入用户名重复否
第一行输入用户名总数后面逐行输入用户名实现判断当前输入用户名是否已存在逐行输出结果YES用户名存在 NO不存在#include <string>using namespace std;class HashTable {private: string *elem; int size;public: HashTable() { size = 2000;原创 2016-05-28 17:25:04 · 424 阅读 · 0 评论 -
二叉树_已知先序中序求后序
二叉树的性质:二叉树的第 i 层最多有 2i - 1 个结点。由定义可知,二叉树的每个结点最多有两个孩子结点,那么第 i 层最多的结点数等于第 i - 1 层最多结点数的 2 倍。而第 1 层最多只有 1 个结点,所以我们可以知道第 i 层最多有 2i - 1 个结点。深度为 k 的二叉树最多有 2k - 1 个结点。由上一个性质,我们可以知道二叉树每层最多的结点个数,从第 1 层到第 k 层把最多原创 2016-05-28 21:09:59 · 437 阅读 · 0 评论 -
Huffman树基本原理介绍
我们把每个字符看成一个结点,权值是字符的频率,每个字符开始都是一棵只有根结点的二叉树,如下图。 1.从集合里取出根结点权值最小的两棵树 I 和 J 组成新的二叉树 IJ,根结点权值为 1 + 1 = 2,将二叉树 IJ 加入集合,把 I 和 J 从集合里删除,如下图。 2.从集合里取出根结点权值最小的两棵树 H 和 G 组成新的二叉树 HG,根结点权值为 1 + 2 = 3,将二叉树 HG转载 2016-05-28 21:20:43 · 270 阅读 · 0 评论 -
二叉树_二叉搜索树_二叉排序树
二叉排序树又称为二叉查找树,二叉搜索树。二叉排序树和普通的二叉树在结构上一样,它要么是一棵空树,要么是这样的一棵二叉树:对任意结点,如果左子树不为空,则左子树上所有结点的权值都小于该结点的权值;如果右子树不为空,则右子树上所有结点的权值都大于该结点的权值;任意结点的左子树和右子树都是一棵二叉排序树;一般而言, 二叉排序树上结点的权值都是唯一的。在二叉排序树上,对于任意结点,如果有左子树和右子树,那么原创 2016-05-29 01:19:46 · 244 阅读 · 0 评论 -
Python实现dict转换成HTML表格
使用for循环的迭代不仅可以迭代普通的list,还可以迭代dict。假设有如下的dict:d = { ‘Adam’: 95, ‘Lisa’: 85, ‘Bart’: 59 } 完全可以通过一个复杂的列表生成式把它变成一个 HTML 表格:tds = [‘%s%s’ % (name, score) for name, score in d.iteritems()] print ‘’ print原创 2016-09-03 12:14:29 · 5855 阅读 · 0 评论