update readme.md

This commit is contained in:
ranwenjie
2021-11-07 00:16:03 +08:00
parent 3a88447c9d
commit 00136b91f9
6 changed files with 68 additions and 17 deletions
+31 -2
View File
@@ -149,7 +149,7 @@ void quicksort(int *a, int left, int right){
### 归并排序merge
分治算法(divide-and-conquer),必然用到递归 ;
分治算法(divide-and-conquer),必然用到递归 ;
2个有序数组的合并操作是O(n)的复杂度
因此我们可以将无序的数组,分成2个子数组分别排序,然后再merge,依次类推
@@ -161,7 +161,7 @@ void quicksort(int *a, int left, int right){
3. 合并
归并排序的代码框架如下:
归并排序的代码框架,套用二叉树的后续遍历思路,如下:
```
void sort(int[] nums, int lo, int hi) {
@@ -174,6 +174,35 @@ void sort(int[] nums, int lo, int hi) {
merge(nums, lo, mid, hi);
/************************/
}
//合并连个有序数组; 从后往前merge
public void merge(int[] arr,int low,int mid,int high,int[] tmp){
int i = 0;
int j = low,k = mid+1; //左边序列和右边序列起始索引
while(j <= mid && k <= high){
if(arr[j] < arr[k]){
tmp[i++] = arr[j++];
}else{
tmp[i++] = arr[k++];
}
}
//若左边序列还有剩余,则将其全部拷贝进tmp[]中
while(j <= mid){
tmp[i++] = arr[j++];
}
while(k <= high){
tmp[i++] = arr[k++];
}
for(int t=0;t<i;t++){
arr[low+t] = tmp[t];
}
}
```
![](./mergesort.gif)
+6 -6
View File
@@ -3,13 +3,14 @@
详细介绍每一种算法设计的思路,并为每种方法给出一个经典案例的详细解读,总结对应设计思路,最后给出其它案例,以供参考。
* [递归](递归.md)
* [分治算法](分治算法.md)
* [动态规划](动态规划.md)
* [回溯法](回溯法.md)
* [迭代法](迭代法.md)
* [穷举搜索法](穷举搜索法.md)
* [动态规划](动态规划.md)
* [贪心算法](贪心算法.md)
* [回溯法](回溯法.md)
* [分治算法](分治算法.md)
* [递归](递归.md)
* [贪心算法](贪心算法.md)
@@ -28,7 +29,6 @@
## 参考
《算法设计与分析基础》 Anany Levitin
http://www.chinaunix.net/old_jh/23/437639.html
+8 -7
View File
@@ -5,12 +5,13 @@
分治算法常用`递归`实现
1) 问题缩小的小规模可以很容易解决
2) 问题可以分解为规模较小相同问题
3) 子问题的解可以合并为该问题的解
4) 各个子问题相互独立,(如果这条不满足,转为`动态规划`求解)
1)问题缩小的小规模可以很容易解决
2)问题可以分解为规模较小相同问题
3)子问题的解可以合并为该问题的解
4)各个子问题相互独立,(如果这条不满足,转为`动态规划`求解)
分治法的步骤:
1. 分解
2. 解决
3. 合并
@@ -24,6 +25,6 @@
#### 其它案例
快速排序
归并排序
最大子数组和
* 快速排序
* [归并排序](../6%20Sort/README.md)
* 最大子数组和
+2 -1
View File
@@ -49,7 +49,8 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问
### DP VS 分治法
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。
与[分治法](分治算法.md)不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。
+1 -1
View File
@@ -5,7 +5,7 @@
在 `递推` 阶段,将大的问题分解成小的问题
在 `回归` 阶段,获得最简单问题的解后,逐级返回,依次得到稍微复杂情况的解,知道获得最终的结果
1) 确定递归公式
1) 确定递归公式 , 比如 斐波那契数列 问题中的 `fib(n)=fib(n-1)+fib(n-2)`
2) 确定边界条件
> 自顶向下的递归,自底向上是迭代
@@ -0,0 +1,20 @@
# Hash映射,分而治之
这里的`Hash映射`是指通过一种映射散列的方式,将海量数据均匀分布在对应的内存或更小的文件中
使用hash映射有个最重要的特点是: `hash值相同的两个串不一定一样,但是两个一样的字符串hash值一定相等`。哈希函数如下:
```
int hash = 0;
for (int i=0;i<s.length();i++){
hash = (R*hash +s.charAt(i)%M);
}
```
大文件映射成多个小文件。具体操作是,比如要拆分到100(M)个文件:
1. 对大文件中的每条记录求hash值,然后对M取余数,即 `hash(R)%M`,结果为K
2. 将记录R按结果K分配到第K个文件,从而完成数据拆分
这样,两条相同的记录肯定会被分配到同一个文件。