![](https://img-blog.csdnimg.cn/20210915110846423.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
算法
文章平均质量分 53
主要写BST,VAL,红黑树,B+,B-以及常见5大算法
xiaoming1999
这个作者很懒,什么都没留下…
展开
-
集装箱装载问题
目录引入问题解题思路代码引入问题有一批共n个集装箱要装上载重量为C1的轮船,其中集装箱i的重量为Wi,且要求确定是否有一个合理的装载方案可将这n个集装箱装上这艘轮船。解题思路利用分支界限算法的思想解决此问题,用到队列式分支界限法。如图所示:图中,左孩子表示选择,右孩子表示未被选择,用广度优先遍历队列,记录每次的cw(已选择的重量)以及bestw(最多可以选择的重量)。代码#include <iostream>#include <st...原创 2021-10-24 16:31:02 · 2486 阅读 · 4 评论 -
5.分支限界算法
分支限界算法类似于回溯算法是在问题的解空间树上搜索问题解的算法。主要有两点不同:1求解目标不同:回溯算法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界算法的求解目标是找出满足约束条件的一个解或者是在满足条件的解中找出某种意义下的最优解。2搜索解空间树的方式不同:回溯算法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或者以最小耗费优先的方式搜索解空间树分支限界算法基本思想:分支限界算法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。在分支限界法中,每一个活节点原创 2021-10-21 20:07:34 · 1722 阅读 · 0 评论 -
4.贪心算法以及例题
目录算法思想例题硬币选择问题部分背包问题柜台提供服务算法思想当一个问题具有最优子结构性质时,可以使用动态规划法求解,但有时候使用贪心算法更简单,更直接而且解决问题效率很高。贪心算法总是做出在当前看起来最好的选择,也就是说贪心算法并不从整体最优考虑,它所做出的选择只是在某种意义上的局部最优解,当然最终希望贪心算法得到的最终结果也是最优的。虽然贪心算法不能对所有问题都能得到整体最优解,但是对于很多问题它能够产生整体最优解或者是趋近于最优解。例题硬币选择问题1,..原创 2021-10-21 17:27:12 · 386 阅读 · 0 评论 -
LCS最长公共子序列
目录LCS最长公共子序列的长度LCS最长公共子序列有两个字符串str1:helloworld X:X1,X2,....Xnstr2:hlweord Y:Y1,Y2,....YmLCS最长公共子序列的长度如果Xn == YmLCS(X[1....n],Y[1...m]) = LCS(x[1...n-1],Y[1....m-1])+1如果Xn != XmLCS(X[1....n],Y[1...m]) = max{LCS(x[1...n],...原创 2021-10-16 09:41:59 · 150 阅读 · 0 评论 -
求序列的最长非降(升序)子序列的长度
解题思路代码实现int main(){ int ar[] = { 5, 3, 4, 1, 8, 7, 9 }; int const n = sizeof(ar) / sizeof(ar[0]); int dp[n ] = { 0 }; dp[0] = 1; int maxval = dp[0]; for (int i = 1; i < n; ++i) { for (int j = 0; j < i; ++j) { if (ar[i] > ar[j原创 2021-10-09 20:17:20 · 145 阅读 · 0 评论 -
求一列数中的最大子段和(数中包括负数,如果全是负数,那么最大字段和为0)
目录解题思路代码实现解题思路代码实现int main(){ int ar[] = { -2, 11, -4, 13, -5, -2 }; int const length = sizeof(ar) / sizeof(ar[0]); int dp[length] = { 0 }; dp[0] = ar[0] < 0 ? 0 : ar[0]; int maxval = dp[0]; for (int i = 0; i < length; ++i)...原创 2021-10-09 20:04:38 · 184 阅读 · 0 评论 -
求斐波那契数列中第i个数值
目录递归代码实现非递归代码实现说起斐波那契数列,大家都应该可以想到一种方法就是递归实现,因为斐波那契每个数就是等于它前两个数之和。递归代码实现#include <stdio.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int cnt = 0;int fabnacci(int num,int dp[]){ i原创 2021-10-09 19:39:18 · 388 阅读 · 0 评论 -
动态规划算法--硬币选择问题
目录引入递归代码实现非递归代码实现引入问题描述:有1,3,5分面额的硬币,给定一个面值11,问组成给定面值所需最少硬币的数量是多少?方法一:采用递归解此问题如上图,我们看到可以将面值11分成很多更小的面值来进行解决,在划分过程中我们可以看到有很多同样的子问题出现,例如第2行的子问题[6]在第4行就出现了2次,如果我们在实现过程中忽略此重复情况将会大大降低实现的效率。递归代码实现#include <stdio.h>#include <stdlib.原创 2021-10-08 21:39:32 · 2074 阅读 · 0 评论 -
3.动态规划算法
算法思想动态规划算法的思想与分治算法类似,也是将待求解的问题划分为若干子问题,按划分的顺序求解子阶段问题前一个子问题的解,为后一子问题的求解提供了有用的信息(最优子结构)。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各个子问题,最后求出原问题的最优解。与分治算法最大的区别:适用于动态规划算法求解的问题,经分解后得到的子问题往往不是互相独立的。如图所示:求解问题的基本步骤动态规划所处理的问题是一个多阶段决策问题,一般由初始状..原创 2021-10-08 20:42:37 · 80 阅读 · 0 评论 -
高精度算法 (加法,乘法) C语言版
函数实现代码#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>typedef struct HighAcc{ char data[1000]; int len;}HighAcc;HighAcc add(HighAcc a, HighAcc b){ HighAc...原创 2019-09-18 14:53:56 · 681 阅读 · 0 评论 -
O(logn)对数时间求中位数
目录中位数引入问题代码实现中位数偶数个数升序序列的中位数 = (n/2 + n/2 +1)/2奇数个数升序序列的中位数 = n/2引入问题有两个升序的数组,长度分别是m和n,求两个数组所有元素的 中位数是多少?要求O(logn)时间完成。如果在两个升序数组中找中位数的话,那么就是找第top k个元素,k就是最中间的那个数字。(m+n+1)/2就是中位数的下标。目的:找两个升序数组的第topk个元素如果找到k,总长度是偶数 ,则(k+(k+1))/2 = 中位.原创 2021-10-07 11:05:47 · 988 阅读 · 0 评论 -
分治算法—求大数的top k问题
目录引入快排划分函数的思想快排划分步骤如图代码实现引入例如问题需要求10万个整数中,值最大(小)的第10 个元素或者值最大(小)的前10个元素。10万个整数如果是有序的那会很简单的就求出,但是如果是无序的,那就很困难。如果我们要将10万个数全部排序的话,那也是效率极低的。这时我们可以采用快排的划分函数的方法来解决此问题。快排划分函数的思想每次设置一个基准数,大于基准数的值放在右边,小于基准数的值放在左边,最后将基准数放在合适的位置,并且记录基准数的下标。快排划分步骤原创 2021-10-07 09:53:29 · 531 阅读 · 0 评论 -
2.分治算法
思想:规模为n的原问题的解无法直接求出,进行问题规模缩减,划分子问题(这里子问题相互独立和原问题解的性质是相同的,只是问题规模缩小了)。如果子问题的规模仍然不够小,再进行子问题划分,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止,最后将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解。分治算法使用条件:(分治算法所能解决的问题一般具有以下几个特征)原问题的规模小到一定的程度就可以容易地解决 原问题可以分解为若干个规模较小的相同问题。即原问题具有最优子结.原创 2021-10-05 19:53:50 · 344 阅读 · 0 评论 -
递归回溯算法之整数选择问题2
问题描述:给定一组2n个整数,从里面选出n个整数,让选择的整数的和与剩下的整数的和的差最小。解题思路:使用子集树,左子树代表选择该节点,右子树代表未选择该节点,当递归遍历到叶子节点的时候,判断此时选择节点的数量是否为n,如果为n,将选择的节点和与未选择的节点和做差,选择最小的即可。如果不为n,返回遍历另一条路径。代码如下:(在代码中加了cnt变量,用来测试遍历叶子节点的次数。)#include <stdio.h>#include <stdlib.h>#inclu.原创 2021-09-29 17:44:25 · 99 阅读 · 0 评论 -
递归回溯算法之整数选择问题1
问题描述:给定一组整数,从里面选出一组整数,让选择的整数的和与剩下的整数的和的差最小解题思路:使用子集树,左子树代表选择该节点,右子树代表未选择该节点,当递归遍历到叶子节点的时候,将选择的节点和与未选择的节点和进行做差,选择最小值即可。(子集树的具体概念以及图解参考递归回溯算法_xiaoming1999的博客-CSDN博客)题解代码如下:#include <stdio.h>#include <stdlib.h>#include <iostream>..原创 2021-09-28 23:42:07 · 142 阅读 · 0 评论 -
1.递归回溯算法
解空间:解空间就是所有解的可能取值构成的空间,一个解往往包含了得到这个解的每一步,往往就是对应解空间树中一条从根节点到叶子节点的路径。子集树和排列树都是一种解空间,它们不是真是存在的数据结构,也就是说并不是真的有这样一棵树,只是抽象出的解空间算法思想: 在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根节点出发深度优先搜索解空间树。当搜索到某一节点时,要先判断该节点是否包含问题的解,如果包含就从该节点出发继续深度搜索下去,否则逐层向上回溯。一般在搜索的过程中都会添加相应的剪枝函数,避免无效.原创 2021-09-28 23:24:05 · 612 阅读 · 0 评论 -
B-树、B+树、B*树
B-树m阶B-树满足:树中每个节点最多有m个孩子 除根结点和叶子节点外,其他每个节点至少有[ceil(m/2)]个孩子 (ceil为取上限的函数) 除根结点之外的节点的关键字的个数n必须满足:[ceil(m/2)-1] <= n <= m-1B-树的插入:如果叶子节点空间足够多,则直接插入在叶子节点的左边或者右边 如果空间满了以致没有足够的空间去添加新的元素,则需要将该节点进行“分裂”,将一半数量的关键字元素分裂到新的其相邻右节点中,中间元素上移到父结点中。 此外,如果在.原创 2021-09-28 16:28:34 · 99 阅读 · 0 评论 -
红黑树插入删除
目录红黑树与AVL树的比较:红黑树的性质:红黑树插入删除实现用到的接口代码:红黑树插入:红黑树插入代码实现如下:红黑树删除:红黑树删除代码实现:红黑树不是一棵平衡树,节点的左右子树高度差长的不超过短的2倍。红黑树与AVL树的比较:操作 AVL 红黑树 平衡树 是 否 增删查时间复杂度 O(logn) O(logn) insert最多旋转的次数 2 2 remove最多旋转的次数 O(.原创 2021-09-26 22:06:42 · 188 阅读 · 0 评论 -
BST树的范围和
看到这个题首先想到利用中序遍历来实现(因为中序遍历的特点就是节点升序),在树不为空时进行操作判断根节点与low的大小,根节点大于low需要在根节点的左子树中找(使用递归,一直查找左子树,直到不满足条件) // L 将此时根节点的值比较看是否在范围内,在的话将值加到sum中 //V 判断根节点与high的大小,根节点小于high需要在根节点的右子树中找(使用递归,一直查找右子树,直到不满足条件) // R代码实现如下:int sum = 0;int rangeSumBST(Node *nod原创 2021-09-17 19:08:53 · 203 阅读 · 0 评论 -
求BST树中序遍历倒数第k个节点
中序遍历的顺序是左根右,要求倒数第k个节点,我们可以将左根右遍历转换成右根左遍历,然后求其正数第k个节点即可。//用户接口 int getVal(int k) { Node *node = getVal(root_, k); if (node == nullptr) { string err = "no No"; err += k; throw err; } else { return node->data_; } }//系.原创 2021-09-17 19:02:55 · 112 阅读 · 0 评论 -
AVL树节点失衡以及增加删除操作
AVL树节点失衡的原因有四点:左孩子的左子树太高了 右孩子的左子树太高了 左孩子的右子树太高了 右孩子的左子树太高了原创 2021-09-17 18:47:40 · 490 阅读 · 0 评论 -
BST树的增删查以及前中后层序遍历的递归非递归操作
#include <iostream>#include <functional>#include <stack>#include <queue>using namespace std;template<typename T,typename Comp=less<T>>class BSTree{public: BSTree() :root_(nullptr) {} ~BSTree() {} //非递归插入操作 .原创 2021-09-15 12:00:05 · 154 阅读 · 0 评论 -
动态规划
王师傅是一名卸货工人,现在有n个货物,由于王师傅一次可以同时卸2个货物,所以决定今天先卸其中的2*m个货物。每次卸货物消耗的体力值计算公式为,假如2个货物的质量分别为x和y,消耗的体力值为(x*y)的4次方,现给出n个货物分别的质量。求王师傅卸完2*m个货物后消耗的体力值是多少。例如:输入: 9 41 3 7 9 10 17 20 22输出:64#define _CRT...原创 2019-09-07 09:32:18 · 332 阅读 · 2 评论 -
二叉树的遍历(递归以及非递归)
递归1.先序遍历(根左右)void BinaryTreePrevOrder(BTNode* root) //先序遍历 根左右 (递归){ if (root) { putchar(root->data);//打印根节点 BinaryTreePrevOrder(root->lchild); BinaryTreePrevOrder(root->rchild)...原创 2019-08-22 19:41:50 · 150 阅读 · 0 评论 -
归并排序
归并排序:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。 (合并过程可以看成树的后序遍历过程)归并排序的步骤如下图:代码实现归并排序:void dealMergeSort(int *src, int *tmp, int start, int end){ if (start >= end) { return; } in...原创 2019-08-24 20:51:24 · 56 阅读 · 0 评论 -
快速计算订单价格
某老板想要一个能快速计算订单价格的程序,请你帮他设计一个类:1、这个类里需要原价和数量,原价从一个数组中读出即可(自行定义数组),数量需要初始化。2、老板会不定期调整价格,调整的方式是通过调整一个价格系数,这个系数乘以原价即为最终价格,这个折扣会影响到所有产品。请你设计出一个类能让老板轻松搞定这一切。#include <iostream>#include <cstd...原创 2019-09-04 14:45:10 · 527 阅读 · 0 评论 -
交换排序 (冒泡排序和快速排序)
冒泡排序:用2层for循环实现,i代表的是趟数,j代表的是每趟比较的次数,每趟冒出i之后最小的数。void bubble(int arr[], int len){ int i = 0, j = 0; for (i = 0; i < len - 1; i++) { int count = 0; //是否进行交换的标记 for (j = 0; j < len - ...原创 2019-08-24 22:35:26 · 246 阅读 · 0 评论 -
插入排序 (直接插入排序和希尔排序)
直接插入排序:当插入第i(i>=1)个元素时,前面的src[0],src[[1],…,src[i-1]已经排好序,此时用src[i]的排序码与src[i-1],src[i-2],…的排序码顺序进行比较,找到插入位置即将src[i]插入,原来位置上的元素顺序后移void InsertSort(int *src, int n) //直接插入 空间复杂度为 n^2.{ ...原创 2019-08-22 20:23:11 · 113 阅读 · 0 评论