diff --git "a/08.\346\240\221\347\273\223\346\236\204/README.md" "b/08.\346\240\221\347\273\223\346\236\204/README.md" index 6052a8b..6ca894d 100644 --- "a/08.\346\240\221\347\273\223\346\236\204/README.md" +++ "b/08.\346\240\221\347\273\223\346\236\204/README.md" @@ -1,5 +1,5 @@ # 树结构 -> 二叉树, 平衡二叉,树,森林 +> 二叉树, 平衡二叉, 树, 森林 ## 二叉树 > 二叉树最多只有二个孩子结点 @@ -42,8 +42,14 @@ see: https://www.bilibili.com/video/av35340449 1. n0 =(n+1)/2 (n0表示0度的叶子结点个数, n为总结点数) ## 完全二叉树的性质 +1. 除了最后一层,其他层的节点个数都是满的,最后一层的节点都靠左排列 1. 求树的高度. log2(N) + 1 (log以2为底,N为所有结点数).例 log2(7) + 1 = 2.x + 1 ~= 3 +## 堆 +1. 堆是一个完全二叉树 +1. 堆的每一个元素都小于等于左右子树的节点的值. +1. 堆中的每个节点的值必须大于等于(或者小于等于)其子树中每个节点的值 + ## 链表表示二叉树 ### 二叉链表 1. 在n个结点的二叉链表中,有(n+1)个空指针域 diff --git "a/16.\346\216\222\345\272\217\347\256\227\346\263\225/09.\346\241\266\346\216\222\345\272\217.go" "b/16.\346\216\222\345\272\217\347\256\227\346\263\225/09.\346\241\266\346\216\222\345\272\217.go" new file mode 100644 index 0000000..980ac47 --- /dev/null +++ "b/16.\346\216\222\345\272\217\347\256\227\346\263\225/09.\346\241\266\346\216\222\345\272\217.go" @@ -0,0 +1,27 @@ +package _6_排序算法 + +//思路:申请最大值的数量的桶, 然后把数值存放在桶的下标里.再循环出>0的下标 + +func BucketSort(arr []int) { + max := getMax(arr) + bucket := make([]int, max + 1) + for i := range arr { + bucket[arr[i]] ++ + } + i := 0 + for k, v := range bucket { + for j := 0; j < v; j ++ { + arr[i] = k + i ++ + } + } +} +func getMax(arr []int) int { + max := arr[0] + for _, v := range arr { + if v > max { + max = v + } + } + return max +} diff --git "a/16.\346\216\222\345\272\217\347\256\227\346\263\225/README.md" "b/16.\346\216\222\345\272\217\347\256\227\346\263\225/README.md" index 09352f6..8a96b1f 100644 --- "a/16.\346\216\222\345\272\217\347\256\227\346\263\225/README.md" +++ "b/16.\346\216\222\345\272\217\347\256\227\346\263\225/README.md" @@ -9,6 +9,13 @@ 1. 基数排序 +## 快速排序 +1. 最好, 平均O(NlogN) +1. 最坏O(n^2) +1. 如何防止降到最坏情况,关键在于分区点的选择. + 1. 第一种:三数取中法, 也就从头, 中, 尾分别取一个数, 然后比较大小, 取中间为分区点.数据比较大时,可以使用5数,10数. + 1. 第二种:随机法.按照概率论来说, 情况不会太差 + ## 算法的对比 ![](https://mubu.com/document_image/f262835e-ad57-4636-8f29-854eb6cf3b65-2746950.jpg) diff --git "a/16.\346\216\222\345\272\217\347\256\227\346\263\225/sort_test.go" "b/16.\346\216\222\345\272\217\347\256\227\346\263\225/sort_test.go" index f647b1d..ca78c9a 100644 --- "a/16.\346\216\222\345\272\217\347\256\227\346\263\225/sort_test.go" +++ "b/16.\346\216\222\345\272\217\347\256\227\346\263\225/sort_test.go" @@ -4,6 +4,7 @@ import ( "fmt" "github.com/yezihack/algo/00.src" "github.com/yezihack/algo/16.排序算法/exercise" + "sort" "testing" ) @@ -227,7 +228,12 @@ func TestQuickSort2(t *testing.T) { arr := []int{8, 3, 2, 5, 4, 1, 7, 6} exercise.QuickSort(arr) fmt.Println(arr) + sort.Ints() } - +func TestBucketSort(t *testing.T) { + arr := []int{8, 3, 2, 5, 4, 1, 7, 6, 3} + BucketSort(arr) + fmt.Println(arr) +} diff --git "a/19.\346\237\245\346\211\276\347\256\227\346\263\225/01.\344\272\214\345\210\206\346\237\245\346\211\276.go" "b/19.\346\237\245\346\211\276\347\256\227\346\263\225/01.\344\272\214\345\210\206\346\237\245\346\211\276.go" new file mode 100644 index 0000000..53277a5 --- /dev/null +++ "b/19.\346\237\245\346\211\276\347\256\227\346\263\225/01.\344\272\214\345\210\206\346\237\245\346\211\276.go" @@ -0,0 +1,151 @@ +package _9_查找算法 + +import ( + "fmt" + "math" +) + +//二分查找: 每一次查找都是折半查找. +//需要注意三点: left <= right +// low + (hight-low)/2 或者 (low+high)>>1 +// low=mid+1, high=mid-1 +func BinarySearch(arr []int, value int) int { + if len(arr) == 0 { + return -1 + } + left, right := 0, len(arr) - 1 + mid := 0 + for left <= right { + mid = (left + right) >> 1 + if value == arr[mid] { + return mid + } else if arr[mid] > value { + right = mid - 1 + } else if arr[mid] < value { + left = mid + 1 + } + } + return -1 +} +//递归实现二分查找 +func BReserveSearch(arr []int, low, high, value int) int { + if low > high { + return -1 + } + mid := (low + high) >> 1 + if arr[mid] == value { + return mid + } else if arr[mid] > value { + return BReserveSearch(arr, low, mid-1, value) + } else { + return BReserveSearch(arr, mid+1, high, value) + } +} +//利用二分查找求平方根 +func BSqrt(x float64) float64 { + var ( + low float64 = 0 + high float64 = x + mid float64 + ) + if x > 0 { + low = 1 + high = x + } else { + low = x + high = 1 + } + mid = low + (high - low) / 2 + for float64(math.Abs(mid * mid - x)) > 0.000001 { + if mid * mid < x { + low = mid + } else { + high = mid + } + mid = low + (high - low) / 2 + } + return mid +} +//数组里出现多个重复的数字,获取最前面的数字下标,如1,2,2,3我们要找2,1后面的2而不是3前面的2 +func BFirstSearch(arr []int, value int) int { + low, high := 0, len(arr)-1 + mid := 0 + for low <= high { + mid = low + (high - low) >> 1 + if arr[mid] > value { + high = mid - 1 + } else if arr[mid] < value { + low = mid + 1 + } else { + //如果是最左边的数,再向前找一个位置一定不是当前要找的值,否则high=mid-1继续向左找 + if mid == 0 || arr[mid-1] != value { + return mid + } else { + high = mid - 1 + } + } + } + return -1 +} +//数组里有多少重复的数,查找到最后一个数字.如1,2,2,3.我们要找到3前面的2,不是1后面的2 +func BLastSearch(arr []int, value int) int { + low, high := 0, len(arr) - 1 + mid := 0 + for low <= high { + mid = low + (high - low) >> 1 + if arr[mid] < value { + low = mid + 1 + } else if arr[mid] > value { + high = mid - 1 + } else { + fmt.Println("mid", mid, "low", low, "high", high) + if mid == len(arr) - 1 || arr[mid + 1] != value { + return mid + } else { + low = mid + 1 + } + } + } + return -1 +} + +//查找第一个大于等于给定值的元素 +func BGtSearch(arr []int, value int) int { + low, high := 0, len(arr)-1 + mid := 0 + for low <= high { + mid = low + (high-low)>>1 + if arr[mid] > value { + high = mid - 1 + } else if arr[mid] < value { + low = mid + 1 + } else { + if mid == len(arr) - 1 || arr[mid + 1] > value { + return mid + 1 + } else { + low = mid + 1 + } + } + } + return -1 +} +//查找最后一个小于等于给定值的元素 +func BLTSearch(arr []int, value int) int { + low, high := 0, len(arr) - 1 + mid := 0 + for low <= high { + mid = low + (high - low) >> 1 + if arr[mid] > value { + high = mid - 1 + } else if arr[mid] < value { + low = mid + 1 + } else { + if mid == 0 || arr[mid-1] < value { + return mid - 1 + } else { + high = mid -1 + } + } + } + return -1 +} diff --git "a/19.\346\237\245\346\211\276\347\256\227\346\263\225/test_test.go" "b/19.\346\237\245\346\211\276\347\256\227\346\263\225/test_test.go" new file mode 100644 index 0000000..0317eb5 --- /dev/null +++ "b/19.\346\237\245\346\211\276\347\256\227\346\263\225/test_test.go" @@ -0,0 +1,52 @@ +package _9_查找算法 + +import ( + "fmt" + "github.com/yezihack/algo/00.src" + "testing" +) + +func TestBinarySearch(t *testing.T) { + arr := []int{1,2,3,4,5,6,7} + src.Asset(1, t, 3, BinarySearch(arr, 4)) + src.Asset(2, t, 0, BinarySearch(arr, 1)) + src.Asset(3, t, 6, BinarySearch(arr, 7)) + src.Asset(4, t, -1, BinarySearch(arr, 70)) + src.Asset(5, t, -1, BinarySearch(arr, -50)) +} +func TestBReserveSearch(t *testing.T) { + arr := []int{1,2,3,4,5,6,7} + src.Asset(1, t, 3, BReserveSearch(arr, 0, len(arr)-1, 4)) + src.Asset(2, t, 0, BReserveSearch(arr, 0, len(arr)-1,1)) + src.Asset(3, t, 6, BReserveSearch(arr, 0, len(arr)-1,7)) + src.Asset(4, t, -1, BReserveSearch(arr, 0, len(arr)-1,70)) + src.Asset(5, t, -1, BReserveSearch(arr, 0, len(arr)-1,-50)) +} +func TestBSqrt(t *testing.T) { + var x float64 = 5 + fmt.Println(BSqrt(x)) +} +func TestFirstSearch(t *testing.T) { + arr := []int{1,2,3,3, 3,4,5} + src.Asset(1, t, 2, BFirstSearch(arr, 3)) +} +func TestBLastSearch(t *testing.T) { + arr := []int{1,2,3,3,4,5} + src.Asset(1, t, 3, BLastSearch(arr, 3)) +} +func TestBGtSearch(t *testing.T) { + arr := []int{1, 3, 5, 7, 9} + src.Asset(1, t, 2, BGtSearch(arr, 4)) + src.Asset(2, t, 1, BGtSearch(arr, 2)) + src.Asset(3, t, 4, BGtSearch(arr, 9)) + src.Asset(4, t, 0, BGtSearch(arr, 1)) + src.Asset(5, t, 4, BGtSearch(arr, 10)) +} +func TestBLTSearch(t *testing.T) { + arr := []int{1, 3, 5, 7, 9} + src.Asset(1, t, 1, BLTSearch(arr, 4)) + src.Asset(2, t, 0, BLTSearch(arr, 1)) + src.Asset(3, t, 4, BLTSearch(arr, 9)) + src.Asset(4, t, 3, BLTSearch(arr, 8)) + src.Asset(5, t, 4, BLTSearch(arr, 81)) +} \ No newline at end of file diff --git "a/20.\345\240\206\347\273\223\346\236\204/README.md" "b/20.\345\240\206\347\273\223\346\236\204/README.md" new file mode 100644 index 0000000..de56b5e --- /dev/null +++ "b/20.\345\240\206\347\273\223\346\236\204/README.md" @@ -0,0 +1,18 @@ +# 堆结构 +> 一种特殊的树, 分小顶堆与大顶堆. +1. 小顶堆的堆顶元素存储整个堆的最小元素.一般用于求TOP K的问题. +1. 大顶堆的堆顶元素存储整个堆的最大元素,一般结合小顶堆求中位数.维护两个堆. + +## 堆的特性 +1. 堆是一个特殊的树 +1. 不稳定排序 +1. 原地排序 +1. 时间复杂度O(nlogn) +1. 堆顶元素是最小值(或最大值),也可说 +1. 属于完全二叉树 +1. 一般使用数组存储. + +## 堆的操作 +1. 堆化: 当插入新元素或删除堆顶元素,我们需要进行对堆的调整.让其重新满足堆的特性 +1. 插入新元素:插入到最 +1. 删除堆顶元素 \ No newline at end of file diff --git a/README.md b/README.md index 0bd9475..2ba6de8 100644 --- a/README.md +++ b/README.md @@ -46,17 +46,14 @@ ## 各种算法已代码实现 1. 极客时间算法: https://github.com/wangzheng0822/algo -## Common Data Structure Operations +## Common Data Structure Operations 1. http://www.bigocheatsheet.com/ ### 时间复杂度 ![](assets/Oalgo.png) - - - ## 学习笔记 1. [王卓老师的<<数据结构与算法>>](https://www.bilibili.com/read/cv3285768) 1. [脑图笔记](https://mubu.com/doc/75lsJgfMh6C) 1. [代码实现](https://github.com/yezihack/algo) -3. 仅供同学们参考,也非常感谢老师推出这么优秀的课程 \ No newline at end of file +3. 仅供同学们参考 \ No newline at end of file