
算法
iwonako
这个作者很懒,什么都没留下…
展开
-
哈希表部分实现
只做了增删查,基本的数据类型和字符串template<class T>class HashMap { template<class T>//基本数据类型 struct item { T _value; item<T>* _next;//用链表,无需扩容 explicit item(T value = 0) :_next(nullptr), _value(value){} }; .原创 2021-07-25 05:43:55 · 129 阅读 · 0 评论 -
桶排序
要知道数据范围,然后定划分多少个区间,暂时不支持负数?template<class T>void my_printAry(T* a, int len) { if (a == nullptr || !len)return; for (int i = 0; i < len; i++)cout << a[i] << " "; cout << endl;}template<class T,int NUM>//分成N..原创 2021-07-23 23:59:41 · 83 阅读 · 0 评论 -
计数排序
void countSort(int* a, int len) { if (a == nullptr || !len)return; int min = a[0], max = a[0]; for (int i = 1; i < len; i++) { if (a[i] > max)max = a[i]; else if (a[i] < min)min = a[i]; } int* cnt = new int[max.原创 2021-07-23 21:34:23 · 87 阅读 · 0 评论 -
外排序简单实现
就是文件读写+败者树实现,交作业了从特定命名格式的文件(temp0.txt,temp1.txt ...,temp%d.txt)中读取数据然后在内存中排序,再输出到另一个文件败者树初始化操作有部分代码与后面循坏排序的代码重复,但不能合并,必须先单独初始化。而且loser数组必须初始化为data数组中最小值的索引,然后再调用调整函数循环排序的结束条件:排序得出的最小值所在文件已经访问到底(EOF)。当第x个文件访问完毕,在败者树中进行比较时,将视为一个很大的值,一直被压在loser[1-i]中,不.原创 2021-07-13 17:13:18 · 175 阅读 · 0 评论 -
基数排序
升序时桶数组和下标绑定,不像其他排序算法那样容易从升序改成降序void radixSort(int* a, int len) { int bit = maxBit(a, len), k, radix = 1, bucket[10] = { 0 }; int* temp = new int[len]; for (int i = 1; i <= bit; i++) {//分别按个位,十位,百位。。进行排序 for (int j = 0; j < 10.原创 2021-07-08 22:52:49 · 76 阅读 · 0 评论 -
堆排序
一般用数组来表示堆,下标为 i 的非根结点的父结点下标为(i-1)/2。下标为 i 的左右子结点分别为 (2i + 1)、(2i + 2)构建堆的思路:n个元素的数组能划分成n/2个子堆进行管理和调整,从下往上调整,但下面的子堆可能受上面的堆调整的影响,是否需要调整子堆,要看移动的结点是否为“叶结点”,或者说是否有左右子结点各个子堆调整。为保持根是最大/最小值,与子结点执行交换操作受影响的下级堆。先判断以被交换的子节点为根的下级堆是否被破坏,是,就重新调整,并再判断下下级堆有无被破坏,一直.原创 2021-07-07 23:48:02 · 111 阅读 · 2 评论 -
直接选择排序
有点像冒泡,但这个是先找到位置然后直接交换,每次确定一个最小的元素,冒泡是一边移动一边比较,每轮确定一个最大/最小的元素。可以改进下,同时找最大和最小的void selectSort(int a[], int len) { for (int i = 0; i < len-1; i++) {//比较n-1次 int min = i; for (int j = i + 1; j < len; j++) {//找最小的元素 if.原创 2021-07-07 17:06:00 · 63 阅读 · 0 评论 -
希尔排序
这个算法原理不难,结合示意图理解。主要思想是通过增量将数组分成多组并进行排序,后续增量减小,排序完成度增加。但不知道为什么用swap也能完成排序,用swap也不太符合排序的过程,只是交换 j 和 j-gap 位置,没有将前面的增量序列中的(j-2gap,j-3gap,...)完全排序void shellSort(int* a, int len) { for (int gap = len / 2; gap >= 1; gap /= 2) { //cout <<.原创 2021-07-07 01:47:28 · 83 阅读 · 0 评论 -
插入排序
比直插有所改善,直插是一次次的进行判断移动。可以先找出插入的位置再移动,其实就是在有序数组中找位置void InsertSort(int a[], int len) { int i, j, low, high, mid, temp; for (i = 1; i <= len - 1; i++) {//下标1~len-1都需要排序 temp = a[i]; low = 0; high = i - 1; while (low &l.原创 2021-07-06 20:04:43 · 71 阅读 · 0 评论 -
查找数组中重复的元素
数组a共n+1个元素,元素取值范围1~n,返回数组中重复的元素之一题目条件限定了数组中一定有重复元素,可以对每个可能的取值1~n计算出现次数。或者划分取值范围为1~m,m+1~n,计算两个取值区间在数组a中出现的总次数,如果范围为1~m的统计次数大于m,说明有重复。但如果有某个符合取值范围的元素数组中出现了0次,那么可能为某个重复次数为两次的元素提供了隐蔽条件,这个重复的元素也无法找出,但说明另一个取值范围内也有元素是重复的int cntRange(int* a, int len, int s.原创 2021-07-06 17:24:06 · 2032 阅读 · 0 评论 -
二叉树遍历 非递归
先序和中序类似,不同点在于访问结点的时机。后序较难,双栈的较容易,常规思路的较难,要多回顾vector<int> preorder(TreeNode* root){ if(!root)return {}; vector<int>v; stack<TreeNode*>s; s.push(root); while(!s.empty()){ root=s.top(); v.push_back(root->val); s.pop();//后面.原创 2021-07-05 17:26:31 · 82 阅读 · 0 评论 -
归并排序
主要是对数组的操作区间要明确,网上很多版本,有的直接传数组长度然后就开始递归了,有的划分左右区间时不用mid+1,最后把temp数组复制到原数组也有各种写法。总之找到一个自己试验过的版本就行void _merge_sort(int a[], int* temp, int l, int r) {//lr闭区间 if (l >= r)return;//只有一个不用再分 int mid = (l + r) / 2; _merge_sort(a, temp, l, mid);.原创 2021-07-04 23:54:13 · 68 阅读 · 0 评论 -
算法题 TOPK问题
牛客网大佬的思路,自己翻译下int partition(vector<int> &input, int l, int r) { int pivot = input[r-1];//以最后一个为基准值 int i = l; for (int j=l; j<r-1; ++j) {//除去最后一个外,进行比较 if (input[j] < pivot) {////小于最后一个的移到前面 .原创 2021-07-04 16:03:14 · 103 阅读 · 0 评论 -
动态规划 过河问题
核心思路:先将n个人的过河速度从小到大排列:a[i],1<=i<=n尽量让速度相近的两个人过河尽量让速度最快的人返回送手电筒原创 2021-06-26 19:00:48 · 604 阅读 · 2 评论