
数据结构与算法
李正浩大魔王
广州 佛山
展开
-
[数据结构]归并排序
算法思想 归并排序与前面介绍过的基于交换、选择等排序的思想不一样,“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。假定待排序表含有n个记录,则可以看成是n个有序的子表,每个子表长度为1,然后两两归并,得到[n/2]个长度为2或1的有序表;再两两归并,……如此重复,直到合并成一个长度为n的有序表为止,这种排序方法称为2-路归并排序。下面给出一个2路归并排序的一个例子: M原创 2017-04-30 17:30:58 · 516 阅读 · 0 评论 -
[数据结构]堆排序
算法思想 堆排序是一种树形选择排序方法,它的特点是:在排序过程中,将L[1…n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(或者最小)的元素。 堆的定义如下:n个关键字序列L[1…n]称为堆,当且仅当该序列满足: ①L(i)≤L(2i)且L(i)≤L(2i)或 ②L(i)≥L(2i)且L(i)≥L(2i+1)原创 2017-04-30 16:41:34 · 860 阅读 · 0 评论 -
[数据结构]冒泡排序
基本思想 冒泡排序算法的基本思想是:假设待排序表长为n,从后往前(或从前往后),两两比较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。我们称它为一趟冒泡,如果将最小的元素交换到待排序序列的第一个位置(关键字小的元素往上“漂浮”,这就是冒泡排序名字的由来)。下一趟冒泡时,前一趟确定的最小元素不再参与比较,待排序列减少一个元素,每趟冒泡的结果把序列中最小元素放到了序列原创 2017-04-29 21:23:40 · 1234 阅读 · 0 评论 -
[数据结构]折半插入排序
上一篇博客介绍了直接插入排序,而折半插入排序就是在直接插入排序的基础上进行了一些改进,有需要的可以看一下。插入的基本思想 ①每次插入,都从前面的有序子表中查找出待插入元素应该被插入的位置; ②给插入位置腾出空间,将待插入元素复制到表中的插入位置。 注意到该算法中,总是边比较边移动元素,下面将比较和移动操作分离开来,即先折半查找出元素的待插入位置,然后再同意地移动待插入位置之后的所有元素原创 2017-04-29 21:00:32 · 25848 阅读 · 3 评论 -
[数据结构]直接插入排序
插入排序的思想 插入排序是一种简单只管的排序方法,其基本思想在于每一次待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。 假设在排序过程中,待排序表L[1….n]在某次排序过程中的某一时刻状态如下: 为了实现将元素L(i)插入到已经有序的子序列L[1…i-1]中,我们需要执行以下操作: 1)查找出L(i)在L[1…i-1]中的插入位置k。原创 2017-04-28 22:32:07 · 3843 阅读 · 4 评论 -
[数据结构]Hash Table(哈希表)
Hash Table基本概念 散列函数:一个把查找表中的关键字映射成该关键字对应的地址的函数,记为Hash(key)=Addr。 散列函数可能会把两个或者两个以上的关键字映射到同一个地址,称这种情况为”冲突“,这里发生碰撞的不同关键字称为”同义词“。一方面,设计好的散列函数应该尽量减少这样的冲突;另一方面,由于这样的冲突总是不可避免的,所以还要设计好的处理冲突的方法。 散列表:是根据关原创 2017-04-28 21:52:01 · 937 阅读 · 0 评论 -
[数据结构]Dijkstra算法求单源最短路径
概念 求带权有向图中某个源点到其余各个顶点的最短路径,最常用的是Dijkstra算法。该算法设置一个集合S记录已求得的最短路径的顶点,可用一个数组s[]来实现,初始化为0,当s[Vi]=1时表示将顶点Vi放入S中,初始时把源点V0放入S中。此外,在构造过程中还设置了两个辅助数组: dist[]:记录了从源点v0到其他各个顶点当前的最短路径长度,dist[i]初值为arcs[V0][i]。原创 2017-04-28 20:23:32 · 1279 阅读 · 0 评论 -
[数据结构]克鲁斯卡尔(Kruskal)算法
算法的概念 与Prim算法从顶点开始扩展最小生成树不同,Kruskal算法是一种按权值的递增次序选择合适的边来构造最小生成树的方法。假设N=(V,E)是连通网,对应的最小生成树T=(Vt,Et),Kruskal算法的步骤如下: 初始化:Vt=V,Et=空集。即每个顶点构成一棵独立的树,T此时是一个仅含|V|个顶点的森林; 循环(重复下列操作至T是一棵树):按G的边的权值第怎顺序依次从E原创 2017-04-28 18:35:41 · 1838 阅读 · 0 评论 -
[数据结构]普里姆(Prim)算法生成最小生成树
前提介绍:最小生成树概念 一个连通图的生成树是图的极小连通子图,它包含图中的所有定点,并且只含尽可能少的边,这意味着对于生成树来说,就砍去使生成树变成非连通图;若给它怎家一条边就会形成图中的一条回路。 对于一个带权连通无向图G=(V,E),生成树不同,每个树的权也可能不同。设W为G的所有生成树的集合,若T为G中边的权值之和最小的那棵生成树,则T成为G的最小生成树。Prim算法概念 Prim原创 2017-04-28 18:00:31 · 5332 阅读 · 0 评论 -
[数据结构]深度优先搜索算法(Depth-First-Search,DFS)
深度优先搜索算法的概念 与广度优先搜索算法不同,深度优先搜索算法类似与树的先序遍历。这种搜索算法所遵循的搜索策略是尽可能“深”地搜索一个图。它的基本思想如下:首先访问图中某一个起始顶点v,然后由v出发,访问与v相邻且未被访问的任一顶点w1,再访问与w1邻接且未被访问的任一顶点w2,….重复上述过程。当不能再继续向下访问时,依次退回到最近被访问的顶点,若它还有邻接顶点未被访问过,则从该点开始继续上述原创 2017-04-27 22:32:34 · 16639 阅读 · 0 评论 -
[数据结构]广度优先搜索算法(Breadth-First-Search,BFS)
广度优先搜索的概念 广度优先搜索(BFS)类似于二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,然后由v出发,依次访问v的各个未被访问过的邻接顶点w1,w2,w3….wn,然后再依次访问w1,w2,…,wi的所有未被访问过的邻接顶点,再从这些访问过的顶点出发,再访问它们所有未被访问过的邻接顶点….以此类推,直到途中所有的顶点都被访问过为止。类似的想法还将应用与Dijkstra单源最短路径算原创 2017-04-27 21:26:22 · 24478 阅读 · 3 评论 -
[数据结构与算法]快速排序的优化实现(取中位数)
#include "iostream"using namespace std;int Partion(int array[], int low, int high);void findMid(int array[], int low, int high);void QuickSort(int array[], int low, int high)//主函数{ if (low<hig原创 2017-08-10 10:54:06 · 1057 阅读 · 0 评论 -
[数据结构与算法]直接插入排序的实现
void InsertSort(int array[],int n) { int i, j,temp; for (i=1;i<n;i++) { if (array[i]<array[i-1])//将array[i]的元素插入前面有序的子序列 { temp = array[i]; for (j = i原创 2017-08-10 22:08:32 · 795 阅读 · 0 评论 -
[数据结构]快速排序
算法思想 快速排序是对冒泡排序的一种改进。其基本思想是基于分治法的;在待排序表L[1….n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],使得L[1….k1]中所有元素小于pivot,L[k+1….n]中所有元素大于或等于pivot,则pivot放在了其最终位置L(k)上,这个过程称作一趟快速排序。而后分别递归地对两个子表重复上...原创 2017-04-30 15:35:25 · 623 阅读 · 0 评论 -
[数据结构]简单选择排序
算法思想假设排序表为A[1….n],第i趟排序即从A[i….n]中选择最小的元素与L(i)交换,每一趟排序可以确定一个元素最终的位置,这样经过n-1次排序就可以使得整个排序表有序(注意与直接插入排序做区分,简单选择排序时从待排元素中选最小值,而直接插入排序是一个一个元素往前移动到合适的位置)算法代码void selectSort(int* A,int n){ for(in...原创 2018-02-27 09:03:29 · 771 阅读 · 2 评论 -
[LeetCode]461. 汉明距离
题目两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。给出两个整数 x 和 y,计算它们之间的汉明距离。注意: 0 ≤ x, y &lt; 2³¹ 示例:输入: x = 1, y = 4输出: 2解释:1 (0 0 0 1)4 (0 1 0 0) ↑ ↑上面的箭头指出了对应二进制位不同的位置。代码...原创 2018-04-22 19:37:41 · 325 阅读 · 0 评论 -
[LeetCode]109. 有序链表转换二叉搜索树
题目 给定一个单元链表,元素按升序排序,将其转换为高度平衡的BST。对于这个问题,一个高度平衡的二叉树是指:其中每个节点的两个子树的深度相差不会超过 1 的二叉树。 例子:给定的排序链表: [-10, -3, 0, 5, 9],则一个可能的答案是:[0, -3, 9, -10, null, 5] 0 / \ -3 9 / /...原创 2018-04-18 19:46:23 · 1014 阅读 · 0 评论 -
[LeetCode]344. 反转字符串
题目 请编写一个函数,其功能是将输入的字符串反转过来。 示例:输入:s = "hello"返回:"olleh"思路 从前往后遍历字符串,遍历的过程中将第i个字符与第length-i-1个字符交换即可代码#include&lt;iostream&gt;using namespace std;class Solution {publ...原创 2018-04-18 19:56:27 · 514 阅读 · 0 评论 -
编程之法 1.3 字符串反转
单词反转 输入一个英文句子,反转句子中单词的顺序,要求单词内字符的顺序不变,句子中单词以空格隔开。为简单期间,标点符号和普通字符一样处理。例如输入“I am a student.”,则输出“student. a am I”。代码思想先进行整体反转 将”I am a student.”翻转为”.tneduts a ma I”再将字符串中每个单词进行反转(可以通过...原创 2018-04-13 23:44:32 · 258 阅读 · 0 评论 -
[LeetCode]226.翻转二叉树——递归遍历交换孩子
题目 翻转一棵二叉树。 4 / \ 2 7 / \ / \1 3 6 9//转换为: 4 / \ 7 2 / \ / \9 6 3 1代码 TreeNode* invertTree(TreeNode* root) { if(root==NULL...原创 2018-04-19 20:23:34 · 287 阅读 · 0 评论 -
[LeetCode]637. 二叉树的层平均值
题目给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.示例 1:输入: 3 / \ 9 20 / \ 15 7输出: [3, 14.5, 11]解释:第0层的平均值是 3, 第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].注意:节点值的范围在32位有符号整数范围内。代码...原创 2018-04-19 20:43:41 · 647 阅读 · 0 评论 -
快速排序——C++左闭右开区间实现
代码#include<iostream>#include<vector>using namespace std;class Solution{public: //快速排序接口 void quickSort(vector<int> &vec, vector<int>::iterator begin, vecto...原创 2018-04-19 22:36:14 · 854 阅读 · 0 评论 -
编程之法1.4字典序的全排列
题目输入一个字符串,已知字符串中的字符是互不相同的,现在把它们任意排列,例如:"ab"字符串可以排列为"aa","ab","ab","bb",编程按照字典序输出所有的结果。代码#include&lt;iostream&gt;using namespace std;cl原创 2018-04-20 21:05:37 · 290 阅读 · 0 评论 -
[LeetCode]1. 两数之和
题目给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]解法class Solution {public: ...原创 2018-04-25 19:59:53 · 368 阅读 · 0 评论 -
[LeetCode]5. 最长回文子串
题目给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。示例 1:输入: "babad"输出: "bab"注意: "aba"也是一个有效答案。示例 2:输入: "cbbd"输出: "bb"代码class Solution {public:原创 2018-04-26 20:28:53 · 305 阅读 · 0 评论 -
[LeetCode]100. 相同的树
题目给定两个二叉树,编写一个函数来检验它们是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。示例 1:输入: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3]输出: true示例 2:输入: ...原创 2018-05-11 19:48:24 · 319 阅读 · 0 评论 -
编程之法第一章习题——删除特定的字符
题目给定一个原始字符串和模式字符串,要求在原始字符串中删除所有在模式字符串中出现过的字符,对应位置用空格占位。要求性能最优。例如:原始字符串为“They are students.”,模式字符串为“aeiou”,那么删除之后得到的字符串为“They r stdnts.”代码#pragma once#include&lt;iostream&gt;#include &l...原创 2018-05-05 20:40:55 · 368 阅读 · 0 评论 -
编程之法第一章习题——6.重复字符的压缩
题目压缩连续出现的字符,例如:字符abcbc由于无连续字符,压缩后的字符串还是“abcbc”。压缩后输出的格式要求为又重复的字符,按字符重复的次数+字符输出,例如,字符串xxxyyyyyyz压缩后输出为3x6yz。 代码#include &lt;iostream&gt;using namespace std;class Solution{public: s...原创 2018-04-27 22:51:44 · 517 阅读 · 0 评论 -
[LeetCode]爬楼梯
题目假设你正在爬楼梯。需要 n 步你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?注意:给定 n 是一个正整数。示例 1:输入: 2输出: 2解释: 有两种方法可以爬到楼顶。1. 1 步 + 1 步2. 2 步示例 2:输入: 3输出: 3解释: 有三种方法可以爬到楼顶。1. 1 步 + 1 步 + 1 步...原创 2018-05-06 20:41:45 · 458 阅读 · 0 评论 -
[LeetCode]819. 最常见的单词
题目给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。题目保证至少有一个词不在禁用列表中,而且答案唯一。禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。示例:输入: paragraph = "Bob hit a ball, the hit BALL flew fa...原创 2018-05-08 17:22:57 · 1154 阅读 · 0 评论 -
[编程之法]2.2 寻找和为定值的两个数
题目输入一个整数和一个整数数组,在数组中查找一对数,满足他们的和正好是输入的那个整数,如果有多对数的和等于输入的整数,输出任意一对即可。例如,如果输入数组[1,2,4,5,7,11,15]和整数15,那么由于4+11=15,因此表明存在两个数能相加为15。代码#include &lt;iostream&gt;#include &lt;vector&gt;#include...原创 2018-06-03 19:34:17 · 267 阅读 · 0 评论 -
[剑指Offer]3.数组中重复的数字
题目找出数组中重复的数字。 在一个长度为n的数组中的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数组。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。代码#include <iostream>#include &...原创 2018-06-03 20:00:34 · 114 阅读 · 0 评论 -
[数据结构]二分查找
思路二分查找适用于有序的顺序表,基本的思路是:首先将给定的关键字key与表array的中间位置的元素进行比较。如果相等,则查找成功,如果不登,则查找的元素一定在表的前半部分或者后半部分。继续缩小范围再进行同样的查找,直到找到为止,或者查完之后仍然没有找到元素。下面给出一次算法的查找过程实例:实例假设数组array为[7,10,13,16,19,29,32,33,37,41,43...原创 2018-06-03 20:23:29 · 17165 阅读 · 5 评论 -
[编程之法]2.3寻找和为定值的多个数
题目输入两个整数n和sum,要求从数列1,2,3...n中随意取出几个数,使得它们的和等于sum,请将其中所有可能的组合列出来。代码class Solution{public: void findNum(int sum, int n) { if (n<=0||sum<=0) { r...原创 2018-06-04 19:29:27 · 341 阅读 · 0 评论 -
[剑指Offer]二维数组中的查找
题目在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。代码class Solution{public: bool func(vector<vector<int>> arr, int val) { ...原创 2018-06-04 20:08:34 · 144 阅读 · 0 评论 -
[剑指Offer]剪绳子
题目给你一根长度为n的绳子,请把绳子剪为m段(m,n都是整数,并且n>1,m>1),每段绳子的长度为k[0],k[1],k[2]…k[m]。请问k[0]×k[1]×…..k[m]可能的最大乘积是多少?例如,当绳子的长度为8时,我们把它剪为2,3,3三段,最大乘积为18。思路我们利用动态规划的思路解决这个问题,想象一下,我们剪第一刀的时候,可以剪出1,2,3…n-...原创 2018-06-05 20:44:37 · 381 阅读 · 0 评论 -
[剑指Offer]二进制中1的个数
题目输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。思路1、算术移位与逻辑移位在计算机指令中,移位操作是一种基本操作,是一种直接对二进制数据的位运算操作。而移位运算又包含了逻辑移位(logical shift)和算术移位(arithmetic shift)两种。逻辑移位:移出去的位丢弃,空缺位(vacant bit)用 0 填充。算术移位:移出去的位丢弃...原创 2018-09-02 19:46:44 · 208 阅读 · 0 评论 -
88. 合并两个有序数组
题目 代码class Solution {public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int i=0; while(i<n) { nums1[m+i...原创 2018-09-16 08:12:51 · 150 阅读 · 0 评论 -
278. 第一个错误的版本
题目 代码// Forward declaration of isBadVersion API.bool isBadVersion(int version);class Solution {public: int firstBadVersion(int n) { int low=1,high=n; while(low<=hig...原创 2018-09-16 08:13:51 · 154 阅读 · 0 评论 -
70. 爬楼梯
题目 代码class Solution {public: int climbStairs(int n) { if(n==1) return 1; int step=0; int step1=1,step2=1; for(int i=1;i<n;i++) ...原创 2018-09-16 08:15:36 · 350 阅读 · 0 评论