
Data Structure
数据结构与算法相关的原理及代码实现
飞、
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
如何分析递归算法的时间复杂度
递归算法的时间复杂度?原创 2020-09-07 13:58:30 · 535 阅读 · 0 评论 -
红黑树
https://www.jianshu.com/p/e136ec79235c原创 2020-09-03 19:02:16 · 84 阅读 · 0 评论 -
并查集 和 STL中的自定义哈希
今天我们要介绍一种简单但对于合并和查找都十分高效的结构——并查集,其底层实现也十分简单,并且应用非常广泛,比如最小生成树算法中的Kruskal算法,里面有使用了并查集的结构!并且在并查集结构为了加速查找,底层使用基于hash的容器,在CPP中,叫做unordered_map! unordered_map是C++11标准的东西,其为基础类型提供了hash模板,但是如果自定义类型呢?我们如何去构建这个容器?unordered_map(自定义类型)在STL库中,我们要注意区别map和unordered_map转载 2020-09-03 17:35:39 · 169 阅读 · 0 评论 -
二叉搜索树
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {}};//二叉树的层序遍历class Solution {public: //二叉搜索树查找 TreeNode* find(TreeNode* root,int val) { if (root == NULL) return NULL; if (root-&原创 2020-08-31 16:39:51 · 110 阅读 · 0 评论 -
二分查找
二分查找:思路很简单,细节是魔鬼。二分查找涉及到很多的细节(比如while循环中的不等号是否应该带等号,mid 是否应该加一等等),需要特别注意。##二分查找的框架int binarySearch(vector<int>& nums, int target) { int L = 0, R= ...; while(...) { int mid =L+ (R-L ) / 2; if (nums[mid] == target) {原创 2020-08-28 14:23:43 · 102 阅读 · 0 评论 -
哈夫曼树
哈夫曼树原创 2020-08-27 14:12:32 · 155 阅读 · 0 评论 -
贪心算法
贪心算法原创 2020-08-27 11:07:19 · 373 阅读 · 0 评论 -
队列
循环队列原创 2020-08-26 10:44:35 · 121 阅读 · 0 评论 -
基数排序
//获取最大元素int GetMaxElement(vector<int>& p, int length){ int i; int max = p[0]; for (i = 0; i < length; ++i) { if (p[i] > max) { max = p[i]; } } return max;}//获取最大位数int GetMaxLoop(int num){ int bits = 1; num /= 10; .原创 2020-08-26 10:10:45 · 91 阅读 · 0 评论 -
桶排序
void BucketSort(vector<int> &arr, int n){ int MAX = arr[0]; for (auto& item:arr) MAX = std::max(MAX, item); vector<int> *bucket = new vector<int>[MAX / 10 + 1]; //每个桶元素是一个指针,指向一个vector for (int i = 0; i < n; i++) { .原创 2020-08-25 16:46:01 · 117 阅读 · 0 评论 -
计数排序
void countSort(vector<int> &arr) { // 找出数组A中的最大值 int MAX=arr[0]; int MIN = arr[0]; for (int num : arr) { MAX = std::max(MAX, num); MIN = std::min(MIN, num); } // 初始化计数数组count vector<int> count(MAX-MIN + 1); // 对计数数组各元素赋值 for (.原创 2020-08-25 16:33:15 · 141 阅读 · 0 评论 -
希尔排序
void shell_sort(vector<int> & arr){ int n = arr.size(); // gap为步长,每次减为原来的一半。 for (int gap = n / 2; gap > 0; gap /= 2) { // 共gap个组,对每一组都执行直接插入排序 for (int i = 0; i < gap; i++) { for (int j = i + gap; j < n; j += gap) {...原创 2020-08-25 16:19:04 · 106 阅读 · 0 评论 -
快速排序
基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。void quickSort(int* a, int L, int R){ if (L < R) { int i=L, j=R, x; x = a[i]; //基准点 while (i < j) { while (i < j &原创 2020-08-25 14:55:27 · 104 阅读 · 0 评论 -
动态规划
例子:1、爬楼梯问题。假设你现在正在爬楼梯,楼梯有 n 级。每次你只能爬 1级或者 2级,那么你有多少种方法爬到楼梯的顶部?分析:状态转移方程:F(n)=F(n-1)+F(n-2);边界条件:F(1)=F(2)=1;int climb_stair(int n) { vector<int> dp(n); //此题只需要存前两个即可,不过为了DP解法的通用性,仍然声明vector个数为N dp[0] = dp[1] = 1; for (int i = 2; i < n; i+原创 2020-08-25 10:08:44 · 140 阅读 · 0 评论 -
KMP算法
一、简介给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题。真前缀和真后缀:“真前缀” 指除了自身以外,一个字符串的全部头部组合;“真后缀” 指除了自身以外,一个字符串的全部尾部组合。KMP算法通过挖掘模式串的前后缀特征,实现在O(m+n)时间复杂度的匹配。二、朴素字符串匹配算法(暴力算法)暴力匹配的时间复杂度为O(mn) ,其中m为 S 的长度, n为 P 的长度。int NaiveStringSearch(string S,原创 2020-08-24 10:53:12 · 208 阅读 · 0 评论 -
Hash表
1.哈希表的定义哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过计算key的hash值,然后将value存放在该位置(将hash值作为下标)处。2.哈希函数一个好的hash函数需要满足下面的条件:尽量使关键字对应的记录均匀分配在哈希表里面。关键字极小的变化可以引起哈希值极大的变化。比较好的哈希函数是time33算法。unsigned long hash(const char* key){ unsigned long hash=0; for(int i=0;i<原创 2020-08-23 15:13:09 · 145 阅读 · 0 评论 -
链表
链表的查找时间复杂度是O(n),插入、删除是O(1),动态分配内存(区别于数组)单向链表循环链表双向链表静态链表静态链表的数据是用数组存储的,但是数据的位置随机,通过游标将数据链起来。静态链表中每个元素定义如下:静态链表包含两条链,数据链和备用链。备用链是用来管理所有可用的数组位置。通常备用链表的表头位于数组下标为0(a[0])的位置,而数据链表的表头位于数组下标N-1的位置(即最后一个元素)。#include<iostream>#include<unordered_m原创 2020-08-23 14:54:13 · 129 阅读 · 0 评论 -
归并排序
#include<iostream>#include<vector>//合并两个有序数组void merge(std::vector<int>& arr, int L, int M, int R) { int left_size = M - L; int right_size = R - M+1; //注意+1 std::vector<int> left_arr(left_size); std::vector<int> ..原创 2020-08-21 20:07:24 · 110 阅读 · 0 评论 -
插入排序
#include <iostream>//一次插入过程,注意设计函数时,n永远表示数组个数void insert(int arr[], int n) { int key = arr[n - 1]; int i = n - 1; while (i >= 1) { if (arr[i - 1] > key) { arr[i] = arr[i - 1]; i--; } else break; } arr[i] = key;}void in原创 2020-08-21 10:18:27 · 89 阅读 · 0 评论 -
选择排序
#include <iostream>//找到最大值放到最后(一次操作)void swap_max(int arr[], int n) { int max = 0; for (int i = 0; i < n; i++) { if (arr[i] > arr[max]) max = i; } int temp = arr[max]; arr[max] = arr[n - 1]; arr[n - 1] = temp;}void select_sort(in原创 2020-08-21 10:05:36 · 79 阅读 · 0 评论 -
冒泡排序
#include <iostream>//一次冒泡过程void bubble(int arr[], int n) { for (int i = 0; i < n - 1; i++) { if (arr[i] > arr[i + 1]) { int temp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = temp; } }}void bubble_sort(int arr[], int n) { fo原创 2020-08-21 09:57:14 · 112 阅读 · 0 评论 -
堆排序
#include<iostream>void swap(int tree[], int i, int j) { int tmp = tree[i]; tree[i] = tree[j]; tree[j] = tmp;}//从i个节点进行heapifyvoid heapify(int tree[], int n, int i) { if (i >= n) return; int c1 = (2 * i + 1) ; //两个子节点 int c2 = (2 * i ..原创 2020-08-20 22:12:23 · 114 阅读 · 0 评论