Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cd61cb6
Update README.md
chengmo03013106 Oct 20, 2018
6d41800
Create kmp 算法
chengmo03013106 Oct 20, 2018
5995839
Update README.md
chengmo03013106 Oct 20, 2018
9f201a6
Create DP 算法
chengmo03013106 Oct 28, 2018
a743538
Update README.md
chengmo03013106 Oct 28, 2018
51c9b78
Create 时间复杂度学习
chengmo03013106 Oct 28, 2018
cc1742b
Update README.md
chengmo03013106 Nov 3, 2018
f2286a6
单项扫描排序
chengmo03013106 Jan 3, 2019
fcf4929
Rename 单项扫描排序 to 单项扫描排序.cpp
chengmo03013106 Jan 3, 2019
721c514
Update README.md
chengmo03013106 Jan 3, 2019
a135197
Update and rename 单项扫描排序.cpp to quick sort.cpp
chengmo03013106 Jan 3, 2019
01edce9
Update quick sort.cpp
chengmo03013106 Jan 3, 2019
d01e083
Update and rename 补充:C语言代码规范.md to C代码笔记.md
chengmo03013106 Jan 4, 2019
60ad730
Delete C代码笔记.md
chengmo03013106 Jan 4, 2019
c3df77d
Update README.md
chengmo03013106 Jan 18, 2019
e392b5c
Update README.md
chengmo03013106 Jan 18, 2019
b21ad66
map using red black tree vs hash map
chengmo03013106 Jan 23, 2019
63248bb
Adding scaling of compartion hash map and map.
chengmo03013106 Jan 23, 2019
114b7bb
Update README.md
chengmo03013106 Jan 23, 2019
c123ffa
Update README.md
chengmo03013106 Jan 23, 2019
217646c
Update README.md
chengmo03013106 Jan 23, 2019
d31b2f2
Update README.md
chengmo03013106 Jan 23, 2019
aa88b30
Update README.md
chengmo03013106 Jan 23, 2019
5ddd476
Update README.md
chengmo03013106 Jan 23, 2019
dd2eaa9
Update README.md
chengmo03013106 Jan 23, 2019
11185dd
Update README.md
chengmo03013106 Jan 23, 2019
51b0ea8
Update README.md
chengmo03013106 Jan 23, 2019
93fdb07
Update README.md
chengmo03013106 Jan 23, 2019
d8c8c73
Update README.md
chengmo03013106 Jan 23, 2019
08142d6
Update README.md
chengmo03013106 Jan 23, 2019
93f596f
Update README.md
chengmo03013106 Jan 29, 2019
bd13aea
C语言代码规范
chengmo03013106 Jan 30, 2019
a6ee9a9
Update README.md
chengmo03013106 Oct 11, 2019
fd814eb
Update README.md
chengmo03013106 Oct 11, 2019
de2426b
Update 堆和栈.md
chengmo03013106 Nov 6, 2019
380cf45
Update README.md
chengmo03013106 Dec 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions 15个经典基础算法/DP 算法
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
三角形问题:
step 1

N = 5
n\r n = 1,2,3...; r=1,2,3...
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

max value = D(r,j)

new max value = max(D(r+1,j),D(r+1,j+1)) + D(r,j)

vvv code vvv
#include <iostream>
#include <algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int n;
int MaxSum(int i, int j){
if(i==n)
return D[i][j];
int x = MaxSum(i+1,j);
int y = MaxSum(i+1,j+1);
return max(x,y)+D[i][j];
}
int main(){
int i,j;
cin >> n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin >> D[i][j];
cout << MaxSum(1,1) << endl;
}

递归转换为递推
#include <iostream>
#include <algorithm>
using namespace std;

#define MAX 101

int D[MAX][MAX];
int n;
int maxSum[MAX][MAX];
int main(){
int i,j;
cin >> n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin >> D[i][j];
for( int i = 1;i <= n; ++ i )
maxSum[n][i] = D[n][i];
for( int i = n-1; i>= 1; --i )
for( int j = 1; j <= i; ++j )
maxSum[i][j] = max(maxSum[i+1][j],maxSum[i+1][j+1]) + D[i][j];
cout << maxSum[1][1] << endl;
}

空间优化后,final step
#include <iostream>
#include <algorithm>
using namespace std;

#define MAX 101

int D[MAX][MAX];
int n;
int * maxSum;

int main(){
int i,j;
cin >> n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin >> D[i][j];
maxSum = D[n]; //maxSum指向第n行
for( int i = n-1; i>= 1; --i )
for( int j = 1; j <= i; ++j )
maxSum[j] = max(maxSum[j],maxSum[j+1]) + D[i][j];
cout << maxSum[1] << endl;
}

四个步骤:
划分主要问题为子问题
确定问题状态,每一个状态,都是一个子问题得到的解
确定初始状态,三角形问题中,初始化边的数量等
确定状态转移方程
定义出什么是“状态”,以及在该“状态”下的“值”
在此之后,就要找出不同的状态之间如何迁移,即如何从一个或多个“值”已知的 “状态”,求出另一个“状态”的“值”(递推型)。
状态的迁移可以用递推公式表示,此递推公式也可被称作“状态转移方程”。
48 changes: 44 additions & 4 deletions 15个经典基础算法/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,61 @@
## Dijkstra:最短路径算法
>Dijkstra是荷兰的计算机科学家,提出”信号量和PV原语“,"解决哲学家就餐问题",”死锁“也是它提出来的

##DP (Dynamic Programming)
动态规划
## DP (Dynamic Programming)
动态规划:
动态规划法所针对的问题有一个显著的特征,即它所对应的子问题树中的子问题呈现大量的重复。动态规划法的关键就在于,对于重复出现的子问题,只在第一次遇到时加以求解,并把答案保存起来,让以后再遇到时直接引用,不必重新求解
经典案例:
1.丢硬币:

2.背包:
一个最优解的子解,也是最优解。

3.最大子数组和问题:

4.三角形问题
https://github.com/chengmo03013106/Learn-Algorithms/blob/master/15%E4%B8%AA%E7%BB%8F%E5%85%B8%E5%9F%BA%E7%A1%80%E7%AE%97%E6%B3%95/DP%20%E7%AE%97%E6%B3%95

##BFS/DFS (广度/深度优先遍历)


##红黑树
## 红黑树

一种自平衡的`二叉查找树`
map和hash_map性能测试
大家都知道在C++的STL中map是使用树来做查找算法,而hash_map使用hash表来排列配对,是使用关键字来计算表位置。那使用起来他们的差别主要是什么呢?对于性能差别是什么,适合什么情况下应用呢?于是我对它们进行了一些测试,并记录了测试数据供大家分享。
测试的内容主要是map和hash_map的添加、删除、查找和遍历操作,首先进行了几组测试,分别是10万次、30万次,时间单位均为毫秒,具体的性能对照如下:

1| hash_map(10万) | map(10万) | hash_map(20万) | map(20万) | hash_map(30万) | map(30万)</br>
2| ------| ------- | ------ | ------ | ------- | ------</br>
3|添加 | 93 | 47 | 156 | 94 | 203 | 172</br>
4|遍历 | 16 | 15 | 16 | 16 | 16 | 15</br>
5|查找 | 0 | 0 | 32 | 31 | 31 | 32</br>
6|删除 | 84 | 2 | 2 | 32 | 33765 | 63 | 76016 | 78</br>


hash_map的添加和删除操作比map要慢,尤其是删除操作hash_map比map可能慢1000倍,从而得到结论是删除和插入操作较多的情况下,map比hash_map的性能更好,添加和删除的数据量越大越明显。


时间单位仍为毫秒:map遍历性能较好,查找性能低于hash map
hash_map(100万) map(100万) hash_map(200万) map(200万) hash_map(300万) map(300万)
遍历 94 31 203 32 297 47
查找 94 234 188 531 281 875

### 结论:
**两大组测试完毕,整体结论也可以得出:一般应用情况下,我们保存的数据不超过100万份,查找的频繁程度不高情况下使用map性能比较好;而保存的数据较多时(超过100万),查找频繁时使用hash_map的性能就高于map了。**


##KMP 字符串匹配算法

##遗传算法

##启发式搜索
## 启发式搜索
启发式简单例子:
内存分配:
***
if num == size
size *= 2
***

##图像特征提取之SIFT算法

Expand Down
107 changes: 107 additions & 0 deletions 15个经典基础算法/map_vs_unorder_map.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include <iostream>
#include <string>
#include <sys/time.h>
#include <map>
#include <unordered_map>
using namespace std;

const int kRunTime1 = 1000*1000; // 循环次数
const int kRunTime2 = 1000*10000;
int main()
{
std::map<int, int> mp;
std::unordered_map<int, int> unordermp;

timeval st, et;

cout << "插入个数 = " << kRunTime1 << endl;
gettimeofday(&st, NULL);
for(int i = 0; i < kRunTime1; ++i)
{
mp.insert(make_pair(i, i));
}
gettimeofday(&et, NULL);
cout << "1 有序map测试时间insert time:" << (et.tv_sec-st.tv_sec)*1000 + (et.tv_usec-st.tv_usec)/1000 << "ms" << endl;

gettimeofday(&st, NULL);
for(int i = 0; i < kRunTime1; ++i)
{
unordermp.insert(make_pair(i, i));
}
gettimeofday(&et, NULL);
cout << "1 无序map测试时间insert time:" << (et.tv_sec-st.tv_sec)*1000 + (et.tv_usec-st.tv_usec)/1000 << "ms" << endl;

cout << "\n插入个数 = " << kRunTime2 << endl;
mp.clear();
gettimeofday(&st, NULL);
for(int i = 0; i < kRunTime2; ++i)
{
mp.insert(make_pair(i, i));
}
gettimeofday(&et, NULL);
cout << "2 有序map测试时间insert time:" << (et.tv_sec-st.tv_sec)*1000 + (et.tv_usec-st.tv_usec)/1000 << "ms" << endl;

mp.clear();
gettimeofday(&st, NULL);
for(int i = 0; i < kRunTime2; ++i)
{
mp.emplace(make_pair(i, i));
}
gettimeofday(&et, NULL);
cout << "2 有序map测试时间emplace time:" << (et.tv_sec-st.tv_sec)*1000 + (et.tv_usec-st.tv_usec)/1000 << "ms" << endl;

unordermp.clear();
gettimeofday(&st, NULL);
for(int i = 0; i < kRunTime2; ++i)
{
unordermp.insert(make_pair(i, i));
}
gettimeofday(&et, NULL);
cout << "2 无序map测试时间insert time:" << (et.tv_sec-st.tv_sec)*1000 + (et.tv_usec-st.tv_usec)/1000 << "ms" << endl;

unordermp.clear();
gettimeofday(&st, NULL);
for(int i = 0; i < kRunTime2; ++i)
{
unordermp.emplace(make_pair(i, i));
}
gettimeofday(&et, NULL);
cout << "2 无序map测试时间emplace time:" << (et.tv_sec-st.tv_sec)*1000 + (et.tv_usec-st.tv_usec)/1000 << "ms" << endl;

return 0;
}
---------------------

/* first round */
插入个数 = 1000000
1 有序map测试时间insert time:922ms
1 无序map测试时间insert time:360ms

插入个数 = 10000000
2 有序map测试时间insert time:10451ms
2 有序map测试时间emplace time:10531ms
2 无序map测试时间insert time:3854ms
2 无序map测试时间emplace time:2956ms
---------------------
/* second round */
插入个数 = 1000000
1 有序map测试时间insert time:918ms
1 无序map测试时间insert time:344ms

插入个数 = 10000000
2 有序map测试时间insert time:10470ms
2 有序map测试时间emplace time:10597ms
2 无序map测试时间insert time:3826ms
2 无序map测试时间emplace time:2932ms
---------------------
/* third round*/
插入个数 = 1000000
1 有序map测试时间insert time:909ms
1 无序map测试时间insert time:376ms

插入个数 = 10000000
2 有序map测试时间insert time:10395ms
2 有序map测试时间emplace time:10505ms
2 无序map测试时间insert time:4015ms
2 无序map测试时间emplace time:3102ms
---------------------
File renamed without changes.
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

这里的内容是我学习算法过程的一些记录,希望能一直坚持下去。

##学习方法
## 学习方法

* 把所有经典算法写一遍
* 看算法有关源码
Expand All @@ -12,7 +12,7 @@
* 刷题


##基本数据结构和算法
## 基本数据结构和算法

这些算法全部自己敲一遍:

Expand All @@ -21,7 +21,7 @@
* 链表
* 双向链表

### 二叉树
### 二叉树, std set,map 就是使用平衡二叉树实现

* 二叉树
* 二叉查找树
Expand All @@ -39,12 +39,12 @@
* 斐波那契堆(Fibonacci Heap)


###哈希表/散列表 (Hash Table)
### 哈希表/散列表 (Hash Table)

* 散列函数
* 碰撞解决

###字符串算法
### 字符串算法

* 排序
* 查找
Expand All @@ -55,7 +55,7 @@
* 数据压缩


###图的算法
### 图的算法

* 图的存储结构和基本操作(建立,遍历,删除节点,添加节点)
* 最小生成树
Expand Down Expand Up @@ -91,14 +91,16 @@
* 哈希表: O(1)


###15个经典基础算法
### 15个经典基础算法

* Hash
* 快速排序
* 快递选择SELECT
* BFS/DFS (广度/深度优先遍历)
* 红黑树 (一种自平衡的`二叉查找树`)
* 红黑树 (一种自平衡的`二叉查找树`):
通过每次插入,删除后旋转,位置红黑树性质,同时以保证最坏情况下时间复杂度仍然可以接受
* KMP 字符串匹配算法
https://github.com/chengmo03013106/Learn-Algorithms/blob/master/%E5%AD%97%E7%AC%A6%E4%B8%B2/kmp%20%E7%AE%97%E6%B3%95
* DP (动态规划 dynamic programming)
* A*寻路算法: 求解最短路径
* Dijkstra:最短路径算法 (八卦下:Dijkstra是荷兰的计算机科学家,提出”信号量和PV原语“,"解决哲学家就餐问题",”死锁“也是它提出来的)
Expand Down Expand Up @@ -223,13 +225,13 @@
[程序员编程艺术](http://blog.csdn.net/v_JULY_v/article/details/6460494)


###基本算法演示
### 基本算法演示

http://sjjg.js.zwu.edu.cn/SFXX/sf1/sfys.html
http://www.cs.usfca.edu/~galles/visualization/Algorithms.html


###编程网站
### 编程网站

http://leetcode.com/
http://openjudge.cn/ 开放在线程序评测平台,可以床架自己的OJ小组
Expand Down
7 changes: 6 additions & 1 deletion 二叉树/3-平衡树AVL/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@

### AVL 实现过程中的问题

不平衡定义:左右子树深度>=2

1. RR,root右旋90度
2. LL,root左旋90度
3. RL,先右旋,再左旋;右旋时,甩锅到小弟,小弟执行右旋90度;领导直接踩在有问题的同事(引起不平衡的节点)头上;然后执行左旋;之前如果有子树,先去掉;等旋转结束后,再回来按照大小处理子树位置。
4. LR,先左旋,再右旋;左旋时,帅锅到小弟,小弟替领导左旋90度;同上,左右相反。

### AVL 实际使用案例

* LLVM 的 ImmutableSet,其底层的实现选择为 AVL 树
* 《一种基于二叉平衡树的P2P覆盖网络的研究》论文
* 《一种基于二叉平衡树的P2P覆盖网络的研究》论文
10 changes: 10 additions & 0 deletions 字符串/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@
* 正则表达式
* 数据压缩

### 十进制数转换成R进制数
思路:将目标十进制数不断除以R,并取余,直到结果为0为止
需要注意的是,最后得到的结果不是数值,而是数值<strong>字符串</strong>

### R进制数转换成十进制数
按权展开
比如二进制 1001001
1*pow(2,0) + 0*pow(2,1) + 0*pow(2,2) + 1*pow(2,3) + 0*pow(2,4) + 0*pow(2,5) + 1*pow(2,6)

r进制数 改用pow(r,数值)

### 排序

Expand Down
Loading