From 7f702254cae840e2a5ef2a6d65ec8dcab0303ccb Mon Sep 17 00:00:00 2001 From: staresgroup Date: Mon, 2 Sep 2019 21:37:19 +0800 Subject: [PATCH 01/33] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E9=98=9F=E5=88=97=E9=81=8D=E5=8E=86for=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/09_queue/CircularQueue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/09_queue/CircularQueue.java b/java/09_queue/CircularQueue.java index 71a988c4..e65313f7 100644 --- a/java/09_queue/CircularQueue.java +++ b/java/09_queue/CircularQueue.java @@ -37,7 +37,7 @@ public String dequeue() { public void printAll() { if (0 == n) return; - for (int i = head; i % n != tail; ++i) { + for (int i = head; i % n != tail; i = (i + 1) % n) { System.out.print(items[i] + " "); } System.out.println(); From a948635286facf14664ba652fd378981bc3c2693 Mon Sep 17 00:00:00 2001 From: "caitlin.gao" Date: Wed, 4 Sep 2019 16:46:48 +0800 Subject: [PATCH 02/33] feat(geektime_algo): add 41 dynamic programming min_dis_path, coin_change --- rust/41_dynamic_programming/coin_change.rs | 20 +++++++++++ rust/41_dynamic_programming/min_dis_path.rs | 38 +++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 rust/41_dynamic_programming/coin_change.rs create mode 100644 rust/41_dynamic_programming/min_dis_path.rs diff --git a/rust/41_dynamic_programming/coin_change.rs b/rust/41_dynamic_programming/coin_change.rs new file mode 100644 index 00000000..adef13da --- /dev/null +++ b/rust/41_dynamic_programming/coin_change.rs @@ -0,0 +1,20 @@ +fn coin_change(coins: Vec, amount: i32) -> i32 { + let mut dp = vec![amount+1; (amount+1) as usize]; + dp[0] = 0; + for i in 1..=amount as usize { + for &coin in coins.iter() { + if i as i32 >= coin { + dp[i] = dp[i].min(dp[i-coin as usize] + 1); + } + } + } + + let last = *dp.last().unwrap(); + if last > amount { -1 } else { last } +} +fn main() { + let coins = vec![1, 3, 5]; + + let m = coin_change(coins, 9); + println!("{}", m); // 3 +} diff --git a/rust/41_dynamic_programming/min_dis_path.rs b/rust/41_dynamic_programming/min_dis_path.rs new file mode 100644 index 00000000..0fe9281a --- /dev/null +++ b/rust/41_dynamic_programming/min_dis_path.rs @@ -0,0 +1,38 @@ +fn min_dis_path(matrix: Vec>) -> i32 { + let m_len = matrix.len(); + if m_len == 0 { return 0; } + + let mut states = vec![vec![0; m_len]; m_len]; + let mut sum = 0; + // 初始化第一行数据 + for j in 0..m_len { + sum += matrix[0][j]; + states[0][j] = sum; + } + + sum = 0; + // 初始化第一列数据 + for i in 0..m_len { + sum += matrix[i][0]; + states[i][0] = sum; + } + + for i in 1..m_len { + for j in 1..m_len { + states[i][j] = matrix[i][j] + states[i-1][j].min(states[i][j-1]) + } + } + + states[m_len-1][m_len-1] +} +fn main() { + let matrix = vec![ + vec![1, 3, 5, 9], + vec![2, 1, 3, 4], + vec![5, 2, 6, 7], + vec![6, 8, 4, 3], + ]; + + let m = min_dis_path(matrix); + println!("{}", m); +} From 8cfaa5d6d82e93abe668b81cfb353cd072833f02 Mon Sep 17 00:00:00 2001 From: huangkui Date: Thu, 5 Sep 2019 08:59:32 +0800 Subject: [PATCH 03/33] =?UTF-8?q?=E5=A0=86=E7=9A=84=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=B1=BB(=E6=9E=84=E5=BB=BA=EF=BC=8C?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E9=A1=B6=E5=A0=86=E5=A0=86=E5=8C=96)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/10_heap/Heap.php | 330 +++++++++++++++++++++++++++++++++++++++++++ php/composer.json | 3 +- 2 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 php/10_heap/Heap.php diff --git a/php/10_heap/Heap.php b/php/10_heap/Heap.php new file mode 100644 index 00000000..1289c61a --- /dev/null +++ b/php/10_heap/Heap.php @@ -0,0 +1,330 @@ +size = $size; + $this->heapType = $heapType; + } + + /** + * @param $data + * 插入并堆化 + */ + public function insert($data) + { + if ($this->isFull()) { + return false; + } + $this->dataArr[$this->count + 1] = $data; + $this->count++; + if ($this->heapType) { + $this->bigHeapLast(); + } else { + $this->smallHeapLast(); + } + } + + /** + * @return bool + * 堆是否满 + */ + public function isFull() + { + if ($this->size == 0) { + return false; + } + if ($this->count >= $this->size) { + return true; + } + return false; + } + public function isEmpty(){ + return empty($this->count)?true:false; + } + //返回堆顶的元素 + public function peak(){ + if($this->isEmpty()){ + return null; + } + return $this->dataArr[1]; + } + + + //只插入 + public function insertOnly($data) + { + if ($this->isFull()) { + return false; + } + $this->dataArr[$this->count + 1] = $data; + $this->count++; + } + + + /** + * 删除堆顶的元素 + * 把最后1个元素插入到堆顶 + * 然后从堆顶开始堆化 + * 返回堆化后的堆顶元素 + */ + public function deleteFirst() + { + $first = $this->dataArr[1]; + $last = array_pop($this->dataArr); + if($this->isEmpty()){ + return null; + } + $this->count--; + $i = 1; + $this->dataArr[$i] = $last; + if ($this->heapType) { + $this->bigHeapFirst(); + } else { + $this->smallHeapFirst(); + } + return $first; + + } + + /** + * 从某一个结点开始向下堆化 + */ + protected function heapFromOneToDown($i) + { + //大根堆 + if ($this->heapType) { + $maxPos = $i; + while (true) { + if (2 * $i <= $this->count) { + if ($this->dataArr[$maxPos] < $this->dataArr[2 * $i]) { + $maxPos = 2 * $i; + } + } + if (2 * $i + 1 <= $this->count) { + if ($this->dataArr[$maxPos] < $this->dataArr[2 * $i + 1]) { + $maxPos = 2 * $i + 1; + } + } + //不需要交换 + if ($i == $maxPos) { + break; + } + $tmp = $this->dataArr[$maxPos]; + $this->dataArr[$maxPos] = $this->dataArr[$i]; + $this->dataArr[$i] = $tmp; + //继续往下堆化 + $i = $maxPos; + + } + } else { + //小根堆 + $minPos = $i; + while (true) { + if (2 * $i <= $this->count) { + if ($this->dataArr[$minPos] > $this->dataArr[2 * $i]) { + $minPos = 2 * $i; + } + } + if (2 * $i + 1 <= $this->count) { + if ($this->dataArr[$minPos] > $this->dataArr[2 * $i + 1]) { + $minPos = 2 * $i + 1; + } + } + //不需要交换 + if ($i == $minPos) { + break; + } + $tmp = $this->dataArr[$minPos]; + $this->dataArr[$minPos] = $this->dataArr[$i]; + $this->dataArr[$i] = $tmp; + //继续往下堆化 + $i = $minPos; + + } + } + + } + + + /** + * 对于1个完全不符合堆性质的 整体堆化 + */ + public function heapAll() + { + for ($i = intval($this->count / 2); $i >= 1; $i--) { + $this->heapFromOneToDown($i); + } + } + + /** + * 堆排序 + * 把堆顶部的元素和数组尾部元素交换 + */ + public function heapSort() + { + $sorted = 0;//已经有序的个数 + while ($sorted < $this->count) { + $i = 1; + $head = $this->dataArr[$i]; + $this->dataArr[$i] = $this->dataArr[$this->count - $sorted]; + $this->dataArr[$this->count - $sorted] = $head; + $sorted++; + + while (true) { + $maxPos = $i; + if (2 * $i <= $this->count - $sorted && $this->dataArr[$maxPos] < $this->dataArr[2 * $i]) { + $maxPos = 2 * $i; + } + if (2 * $i + 1 <= $this->count - $sorted && $this->dataArr[$maxPos] < $this->dataArr[2 * $i + 1]) { + $maxPos = 2 * $i + 1; + } + if ($i == $maxPos) { + break; + } + $tmp = $this->dataArr[$i]; + $this->dataArr[$i] = $this->dataArr[$maxPos]; + $this->dataArr[$maxPos] = $tmp; + $i = $maxPos; + } + } + + } + + /** + *小顶堆 堆化 + * 插入时 + * 堆化最后1个元素 + */ + public function smallHeapLast() + { + $i = $this->count; + while (true) { + $smallPos = $i; + $parent = intval($i / 2); + if ($parent >= 1) { + if ($this->dataArr[$smallPos] < $this->dataArr[$parent]) { + $smallPos = $parent; + } + } + if ($smallPos == $i) { + break; + } + $tmp = $this->dataArr[$smallPos]; + $this->dataArr[$smallPos] = $this->dataArr[$i]; + $this->dataArr[$i] = $tmp; + $i = $smallPos; + } + } + + /** + * 小根堆 + * 堆化根部元素(第一个元素) + */ + public function smallHeapFirst() + { + $i = 1; + while (true) { + $smallpos = $i; + $left = 2 * $i; + if ($left <= $this->count) { + if ($this->dataArr[$smallpos] > $this->dataArr[$left]) { + $smallpos = $left; + } + } + $right = $left + 1; + if ($right <= $this->count) { + if ($this->dataArr[$smallpos] > $this->dataArr[$right]) { + $smallpos = $right; + } + } + if ($smallpos == $i) { + break; + } + $tmp = $this->dataArr[$i]; + $this->dataArr[$i] = $this->dataArr[$smallpos]; + $this->dataArr[$smallpos] = $tmp; + $i = $smallpos; + } + + } + + /** + * 大根堆 + * 堆化根部元素(第一个元素) + */ + public function bigHeapFirst() + { + $i = 1; + while (true) { + $maxpos = $i; + $left = 2 * $i; + if ($left <= $this->count) { + if ($this->dataArr[$maxpos] < $this->dataArr[$left]) { + $maxpos = $left; + } + } + $right = $left + 1; + if ($right <= $this->count) { + if ($this->dataArr[$maxpos] < $this->dataArr[$right]) { + $maxpos = $right; + } + } + if ($maxpos == $i) { + break; + } + $tmp = $this->dataArr[$i]; + $this->dataArr[$i] = $this->dataArr[$maxpos]; + $this->dataArr[$maxpos] = $tmp; + $i = $maxpos; + } + + } + //大根堆, 插入节点后放到数组最后面,然后从插入的节点自下而上开始堆化 + //这里只堆化插入元素相关的节点(就是说,如果没插入这个元素,这个是一个堆) + public function bigHeapLast() + { + $i = $this->count; + while (intval($i / 2) > 0 && $this->dataArr[$i] > $this->dataArr[intval($i / 2)]) { + $tmp = $this->dataArr[$i]; + $this->dataArr[$i] = $this->dataArr[intval($i / 2)]; + $this->dataArr[intval($i / 2)] = $tmp; + $i = $i / 2; + } + } + + /** + * @param $data + */ + public function topn($data) + { + //堆满了 + if ($this->isFull()) { + if ($data > $this->dataArr[1]) { + $this->dataArr[1] = $data; + $this->smallHeapFirst(); + } + } else { + $this->dataArr[$this->count + 1] = $data; + $this->count++; + $this->smallHeapLast(); + + } + return $this->dataArr[1]; + + } + + + +} + + + + diff --git a/php/composer.json b/php/composer.json index ee6e4b1c..e2b480e1 100644 --- a/php/composer.json +++ b/php/composer.json @@ -9,7 +9,8 @@ "Algo_07\\": "07_linkedlist/", "Algo_08\\": "08_stack/", "Algo_09\\": "09_queue/", - "Algo_24\\": "24_tree/" + "Algo_24\\": "24_tree/", + "Algo_10\\": "10_heap/" } } } From 2649cbda828012ba0760d175e70e2f154418f57b Mon Sep 17 00:00:00 2001 From: huangkui Date: Thu, 5 Sep 2019 08:59:56 +0800 Subject: [PATCH 04/33] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=A0=86=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=EF=BC=8C=E5=A0=86=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/10_heap/main.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 php/10_heap/main.php diff --git a/php/10_heap/main.php b/php/10_heap/main.php new file mode 100644 index 00000000..72e3218a --- /dev/null +++ b/php/10_heap/main.php @@ -0,0 +1,30 @@ +insert($v); +} + +while(($r=$heap->deleteFirst())!==null){ + echo $r." "; +} +echo PHP_EOL; + +$heap1=new Heap(10); + +foreach ($arr as $v){ + $heap1->insertOnly($v); +} + + + +$heap1->heapAll(); +//堆化后的 +print_r($heap1->dataArr); +//堆排序 +$heap1->heapSort(); +print_r($heap1->dataArr); From e926928b344ba8f7f9b13c58b65647ffc926d4a5 Mon Sep 17 00:00:00 2001 From: huangkui Date: Thu, 5 Sep 2019 09:00:36 +0800 Subject: [PATCH 05/33] =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=B5=81=E6=9F=A5=E6=89=BEtop=20k=E5=A4=A7=E5=85=83=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/10_heap/topn.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 php/10_heap/topn.php diff --git a/php/10_heap/topn.php b/php/10_heap/topn.php new file mode 100644 index 00000000..5aa5a193 --- /dev/null +++ b/php/10_heap/topn.php @@ -0,0 +1,26 @@ +".$heap->topn($v).PHP_EOL; +} From d6dfd94d430111b89d7e7002c37b01ca4b058a25 Mon Sep 17 00:00:00 2001 From: huangkui Date: Thu, 5 Sep 2019 09:01:04 +0800 Subject: [PATCH 06/33] =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=B5=81=E6=9F=A5=E4=B8=AD=E4=BD=8D=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/10_heap/findmiddle.php | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 php/10_heap/findmiddle.php diff --git a/php/10_heap/findmiddle.php b/php/10_heap/findmiddle.php new file mode 100644 index 00000000..817d4f84 --- /dev/null +++ b/php/10_heap/findmiddle.php @@ -0,0 +1,56 @@ + $v) { + if ($bigHeap->isEmpty()) { + $bigHeap->insert($v); + } else { + $bigPeak = $bigHeap->peak(); + if ($v < $bigPeak) { + $bigHeap->insert($v); + } else { + $smallHeap->insert($v); + } + + if ($bigHeap->count - $smallHeap->count > 1) { + $bigPeak = $bigHeap->deleteFirst(); + $smallHeap->insert($bigPeak); + } elseif ($smallHeap->count - $bigHeap->count > 1) { + $smallPeak = $smallHeap->deleteFirst(); + $bigHeap->insert($smallPeak); + } + + } + //实时获取中位数 + echo "现在的中位数为:".implode(',', midPeak($bigHeap, $smallHeap)) . PHP_EOL; + } + + +} + +function midPeak($heap1, $heap2) +{ + if ($heap1->count == $heap2->count) { + $midArr = [$heap1->peak(), $heap2->peak()]; + } elseif ($heap2->count > $heap1->count) { + $midArr = [$heap2->peak()]; + } else { + $midArr = [$heap1->peak()]; + } + return $midArr; +} From 631536e73a8ad411ce251abfbae10c8414535eee Mon Sep 17 00:00:00 2001 From: huangkui Date: Thu, 5 Sep 2019 09:04:53 +0800 Subject: [PATCH 07/33] =?UTF-8?q?=E5=A0=86=E7=9A=84=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E6=93=8D=E4=BD=9C(=E5=A4=A7=E9=A1=B6=E5=A0=86=EF=BC=8C?= =?UTF-8?q?=E5=B0=8F=E9=A1=B6=E5=A0=86=20=E5=87=A0=E7=A7=8D=E5=A0=86?= =?UTF-8?q?=E5=8C=96=E6=96=B9=E5=BC=8F=EF=BC=8C=E5=A0=86=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=EF=BC=8C=E5=8A=A8=E6=80=81=E6=95=B0=E6=8D=AE=E6=B5=81=E6=9F=A5?= =?UTF-8?q?top=20k=20,=E6=9F=A5=E4=B8=AD=E4=BD=8D=E6=95=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/10_heap/Heap.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/10_heap/Heap.php b/php/10_heap/Heap.php index 1289c61a..7c3f3be3 100644 --- a/php/10_heap/Heap.php +++ b/php/10_heap/Heap.php @@ -1,4 +1,11 @@ Date: Thu, 5 Sep 2019 09:08:59 +0800 Subject: [PATCH 08/33] =?UTF-8?q?=E5=A0=86=E6=93=8D=E4=BD=9C=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84readme=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/README.md b/php/README.md index aabcd3ce..2b14eee1 100644 --- a/php/README.md +++ b/php/README.md @@ -21,3 +21,7 @@ #### 09_stack * 队列链表实现 +#### 10_heap +* main 堆的基本操作,堆排序 +* findmiddle 动态数据流求中位数 +* topn 动态数据流求top k From 3e7b14e83e159264ee52a87b142803a74927bbad Mon Sep 17 00:00:00 2001 From: "caitlin.gao" Date: Thu, 5 Sep 2019 13:55:55 +0800 Subject: [PATCH 09/33] feat(geektime_algo): add 42 dynamic programming edit_distance, longest_increasing_subsequence --- rust/42_dynamic_programming/edit_distance.rs | 29 +++++++++++++++++++ .../longest_increasing_subsequence.rs | 22 ++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 rust/42_dynamic_programming/edit_distance.rs create mode 100644 rust/42_dynamic_programming/longest_increasing_subsequence.rs diff --git a/rust/42_dynamic_programming/edit_distance.rs b/rust/42_dynamic_programming/edit_distance.rs new file mode 100644 index 00000000..2cf50975 --- /dev/null +++ b/rust/42_dynamic_programming/edit_distance.rs @@ -0,0 +1,29 @@ +// leetcode 72 [edit_distance](https://leetcode.com/problems/edit-distance/) +fn edit_distance(word1: &str, word2: &str) -> i32 { + let word1_chars: Vec = word1.chars().collect(); + let word2_chars: Vec = word2.chars().collect(); + let m = word1.len(); + let n = word2.len(); + let mut dp = vec![vec![0; m+1]; n+1]; + + // 初始化第一行 + for i in 0..=m { dp[i][0] = i; } + // 初始化第一列 + for j in 0..=n { dp[0][j] = j; } + + for i in 1..=m { + for j in 1..=n { + let mut step = 0; + if word1_chars[i-1] != word2_chars[j-1] { step = 1; } + dp[i][j] = (dp[i][j-1] + 1).min(dp[i-1][j] + 1).min(dp[i-1][j-1] + step); + } + } + + dp[m][n] as i32 +} +fn main() { + let word1 = "mitcmu"; + let word2 = "mtacnu"; + let m = edit_distance(word1, word2); + println!("{:?}", m); +} diff --git a/rust/42_dynamic_programming/longest_increasing_subsequence.rs b/rust/42_dynamic_programming/longest_increasing_subsequence.rs new file mode 100644 index 00000000..bf4f71ca --- /dev/null +++ b/rust/42_dynamic_programming/longest_increasing_subsequence.rs @@ -0,0 +1,22 @@ +// leetcode 300 [longest_increasing_subsequence](https://leetcode.com/problems/longest-increasing-subsequence) +fn longest_increasing_subsequence(nums: Vec) -> i32 { + if nums.len() <= 1 { return nums.len() as i32; } + + let mut dp = vec![1; nums.len()]; + let mut max_list = 1; + + for i in 0..nums.len() { + for j in 0..i { + if nums[i] > nums[j] { + dp[i] = dp[i].max(dp[j]+1); + } + } + max_list = max_list.max(dp[i]); + } + max_list +} +fn main() { + let nums = vec![2, 9, 3, 6, 5, 1, 7]; + let m = longest_increasing_subsequence(nums); + println!("{:?}", m); +} From 43eb2bb1d0067543e93c3440e7235d857d71a1bd Mon Sep 17 00:00:00 2001 From: fanrui <1996fanrui@gmail.com> Date: Tue, 10 Sep 2019 19:42:49 +0800 Subject: [PATCH 10/33] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20randomLevel?= =?UTF-8?q?=20=E7=9A=84=E7=94=9F=E6=88=90=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/17_skiplist/SkipList.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/java/17_skiplist/SkipList.java b/java/17_skiplist/SkipList.java index 9ffff488..a2a92f24 100644 --- a/java/17_skiplist/SkipList.java +++ b/java/17_skiplist/SkipList.java @@ -1,6 +1,5 @@ package skiplist; -import java.util.Random; /** * 跳表的一种实现方法。 @@ -10,14 +9,13 @@ */ public class SkipList { + private static final float SKIPLIST_P = 0.5f; private static final int MAX_LEVEL = 16; private int levelCount = 1; private Node head = new Node(); // 带头链表 - private Random r = new Random(); - public Node find(int value) { Node p = head; for (int i = levelCount - 1; i >= 0; --i) { @@ -86,15 +84,13 @@ public void delete(int value) { } - // 随机 level 次,如果是奇数层数 +1,防止伪随机 - private int randomLevel() { + // 随机函数期望的目标是 50% 的 Level1,25% 的 Level2,12.5% 的 Level3 + // 一直到最顶层,因为这里每一层的晋升概率是 SKIPLIST_P = 50%,可以通过 SKIPLIST_P 来修改晋升概率 + private int randomLevel() { int level = 1; - for (int i = 1; i < MAX_LEVEL; ++i) { - if (r.nextInt() % 2 == 1) { - level++; - } - } + while (Math.random() < SKIPLIST_P && level < MAX_LEVEL) + level += 1; return level; } From 8d587bbfc63e58e5fda677482a6b9330557ee87c Mon Sep 17 00:00:00 2001 From: fanrui <1996fanrui@gmail.com> Date: Tue, 10 Sep 2019 19:53:22 +0800 Subject: [PATCH 11/33] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20randomLevel?= =?UTF-8?q?=20=E6=B3=A8=E9=87=8A=EF=BC=8C=E4=BE=BF=E4=BA=8E=E7=90=86?= =?UTF-8?q?=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/17_skiplist/SkipList.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/java/17_skiplist/SkipList.java b/java/17_skiplist/SkipList.java index a2a92f24..83acedf1 100644 --- a/java/17_skiplist/SkipList.java +++ b/java/17_skiplist/SkipList.java @@ -84,8 +84,12 @@ public void delete(int value) { } - // 随机函数期望的目标是 50% 的 Level1,25% 的 Level2,12.5% 的 Level3 - // 一直到最顶层,因为这里每一层的晋升概率是 SKIPLIST_P = 50%,可以通过 SKIPLIST_P 来修改晋升概率 + // 理论来讲,一级索引中元素个数应该占原始数据的 50%,二级索引中元素个数占 25%,三级索引12.5% ,一直到最顶层。 + // 因为这里每一层的晋升概率是 50%。对于每一个新插入的节点,都需要调用 randomLevel 生成一个合理的层数。 + // 该 randomLevel 方法会随机生成 1~MAX_LEVEL 之间的数,且 : + // 50%的概率返回 1 + // 25%的概率返回 2 + // 12.5%的概率返回 3 ... private int randomLevel() { int level = 1; From aa36fccf26f3849b3a11143589258723a3de1959 Mon Sep 17 00:00:00 2001 From: Fish_ Date: Wed, 18 Sep 2019 17:15:29 +0800 Subject: [PATCH 12/33] fix: 'counting_sort' panicked at 'index out of bounds... --- rust/13_sorts/counting_sort.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rust/13_sorts/counting_sort.rs b/rust/13_sorts/counting_sort.rs index cf8fc03b..362eed71 100644 --- a/rust/13_sorts/counting_sort.rs +++ b/rust/13_sorts/counting_sort.rs @@ -7,13 +7,14 @@ pub fn counting_sort(mut nums: Vec) -> Vec { let nums_len = nums.len(); // 获取最大数 let mut max = nums[0]; - // 申请一个长度为 max + 1 的新数组 - let mut bucket = vec![0; (max+1) as usize]; + let mut tmp = vec![0; nums_len]; for i in 1..nums_len { if max < nums[i] { max = nums[i]; } } + // 申请一个长度为 max + 1 的新数组 + let mut bucket = vec![0; (max+1) as usize]; for i in 0..nums_len { bucket[nums[i] as usize] += 1; From 733d00f5b4fad4e45b2a2af0956da9cce263a60f Mon Sep 17 00:00:00 2001 From: hkui <764432054@qq.com> Date: Mon, 23 Sep 2019 19:15:48 +0800 Subject: [PATCH 13/33] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=B8=AD=E5=BA=8F=E5=90=8E=E7=BB=AD=EF=BC=8C=E5=B1=82?= =?UTF-8?q?=E7=BA=A7=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/24_tree/Tree.php | 54 ++++++++++++++++++++++++++++++++++++++ php/24_tree/levelOrder.php | 34 ++++++++++++++++++++++++ php/24_tree/main.php | 10 ++++++- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 php/24_tree/levelOrder.php diff --git a/php/24_tree/Tree.php b/php/24_tree/Tree.php index 97fd14b7..282e4561 100644 --- a/php/24_tree/Tree.php +++ b/php/24_tree/Tree.php @@ -149,4 +149,58 @@ public function preOrder($node) $this->preOrder($node->left); $this->preOrder($node->right); } + + /**中序遍历 + * @param $node + * + */ + public function inOrder($node){ + if(empty($node)){ + return; + } + $this->inOrder($node->left); + echo $node->data . ' '; + $this->inOrder($node->right); + + } + + /** + * @param $node + * 后续遍历 + */ + public function postOrder($node){ + if(empty($node)){ + return; + } + $this->postOrder($node->left); + $this->postOrder($node->right); + echo $node->data . ' '; + + } + /** + * @param $queue + * @param int $index 从队列(数组)的那个位置开始处理 + * 层级遍历 + * 首先把节点放入数组,记录放入数组的根节点个数index,把节点的左右子放入数组 + * 开始遍历数组queue(从index开始,子节点已经入队列的节点元素不再处理),把左右子节点放入queue,index++ + * 持续上述过程,当节点没有子节点时,入队列过程结束,queue里节点的顺序即为层级遍历元素节点的顺序 + */ + public function levelOrder(&$queue,$index=0){ + $len=count($queue); + for($i=$index;$i<$len;$i++){ + $node=$queue[$i]; + if($node->left){ + $queue[]=$node->left; + }else{ + return; + } + if($node->right){ + $queue[]=$node->right; + }else{ + return ; + } + $index++; + } + $this->levelOrder($queue,$index); + } } \ No newline at end of file diff --git a/php/24_tree/levelOrder.php b/php/24_tree/levelOrder.php new file mode 100644 index 00000000..273813ba --- /dev/null +++ b/php/24_tree/levelOrder.php @@ -0,0 +1,34 @@ +insert(16); +$tree->insert(30); +$tree->insert(12); +$tree->insert(19); + +$tree->insert(10); +$tree->insert(15); +$tree->insert(18); +$tree->insert(21); +$tree->insert(38); + +$q=[$tree->head]; +$tree->levelOrder($q); + +foreach ($q as $n){ + echo $n->data." "; +} +echo PHP_EOL; \ No newline at end of file diff --git a/php/24_tree/main.php b/php/24_tree/main.php index f68ba9f3..446c5772 100644 --- a/php/24_tree/main.php +++ b/php/24_tree/main.php @@ -9,6 +9,7 @@ $tree->insert(20); $tree->insert(30); +$tree->insert(40); $tree->insert(10); $tree->insert(21); $tree->insert(22); @@ -16,7 +17,14 @@ $tree->preOrder($tree->head); echo PHP_EOL; -var_dump($tree->find(30)); +$tree->inOrder($tree->head); +echo PHP_EOL; + +$tree->postOrder($tree->head); +echo PHP_EOL; + + +print_r($tree->find(30)); echo PHP_EOL; From bc975cca37ea28b8f8fb436f9d738e01347ce617 Mon Sep 17 00:00:00 2001 From: hkui <764432054@qq.com> Date: Mon, 23 Sep 2019 19:19:07 +0800 Subject: [PATCH 14/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B9=8B=E5=89=8Dgithu?= =?UTF-8?q?b=E4=BD=9C=E8=80=85=E4=BF=A1=E6=81=AF(=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E4=BD=9C=E8=80=85=E4=BF=A1=E6=81=AF=E9=94=99=E8=AF=AF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/10_heap/Heap.php | 1 + php/10_heap/findmiddle.php | 5 +++++ php/10_heap/main.php | 6 ++++++ php/10_heap/topn.php | 5 ++++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/php/10_heap/Heap.php b/php/10_heap/Heap.php index 7c3f3be3..07bab5ee 100644 --- a/php/10_heap/Heap.php +++ b/php/10_heap/Heap.php @@ -5,6 +5,7 @@ * Date: 2019/9/5 * Time: 9:01 * 堆的基本操作(大顶堆,小顶堆 几种堆化方式,堆排序,动态数据流查top k ,查中位数) + * */ namespace Algo_10; diff --git a/php/10_heap/findmiddle.php b/php/10_heap/findmiddle.php index 817d4f84..14e9a717 100644 --- a/php/10_heap/findmiddle.php +++ b/php/10_heap/findmiddle.php @@ -1,4 +1,9 @@ Date: Mon, 23 Sep 2019 21:51:23 +0800 Subject: [PATCH 15/33] =?UTF-8?q?=E5=B1=82=E7=BA=A7=E9=81=8D=E5=8E=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/24_tree/Tree.php | 27 ++++++++++++++------------- php/24_tree/levelOrder.php | 4 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/php/24_tree/Tree.php b/php/24_tree/Tree.php index 282e4561..69fdbd2d 100644 --- a/php/24_tree/Tree.php +++ b/php/24_tree/Tree.php @@ -185,22 +185,23 @@ public function postOrder($node){ * 开始遍历数组queue(从index开始,子节点已经入队列的节点元素不再处理),把左右子节点放入queue,index++ * 持续上述过程,当节点没有子节点时,入队列过程结束,queue里节点的顺序即为层级遍历元素节点的顺序 */ - public function levelOrder(&$queue,$index=0){ - $len=count($queue); - for($i=$index;$i<$len;$i++){ - $node=$queue[$i]; - if($node->left){ - $queue[]=$node->left; - }else{ - return; + public function levelOrder($queue, $index = 0) + { + for ($i = $index; $i < count($queue); $i++) { + $node = $queue[$i]; + if ($node->left) { + $queue[] = $node->left; + } else { + return $queue; } - if($node->right){ - $queue[]=$node->right; - }else{ - return ; + if ($node->right) { + $queue[] = $node->right; + } else { + return $queue; } $index++; } - $this->levelOrder($queue,$index); + return $queue; + } } \ No newline at end of file diff --git a/php/24_tree/levelOrder.php b/php/24_tree/levelOrder.php index 273813ba..a3eb93fc 100644 --- a/php/24_tree/levelOrder.php +++ b/php/24_tree/levelOrder.php @@ -25,8 +25,8 @@ $tree->insert(21); $tree->insert(38); -$q=[$tree->head]; -$tree->levelOrder($q); + +$q=$tree->levelOrder([$tree->head]); foreach ($q as $n){ echo $n->data." "; From 8abe29317dc2ede16102fd0cb1ba99340c1e0a64 Mon Sep 17 00:00:00 2001 From: hk <764432054@qq.com> Date: Mon, 23 Sep 2019 21:54:16 +0800 Subject: [PATCH 16/33] comment --- php/24_tree/Tree.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/24_tree/Tree.php b/php/24_tree/Tree.php index 69fdbd2d..b5ea389d 100644 --- a/php/24_tree/Tree.php +++ b/php/24_tree/Tree.php @@ -184,6 +184,8 @@ public function postOrder($node){ * 首先把节点放入数组,记录放入数组的根节点个数index,把节点的左右子放入数组 * 开始遍历数组queue(从index开始,子节点已经入队列的节点元素不再处理),把左右子节点放入queue,index++ * 持续上述过程,当节点没有子节点时,入队列过程结束,queue里节点的顺序即为层级遍历元素节点的顺序 + * + * 完全二叉树 */ public function levelOrder($queue, $index = 0) { From 0ce74598b6ded5550d505d49a5fd7898357001a0 Mon Sep 17 00:00:00 2001 From: hkui <764432054@qq.com> Date: Tue, 24 Sep 2019 09:09:09 +0800 Subject: [PATCH 17/33] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A0=91=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=9A=84readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/README.md b/php/README.md index 2b14eee1..57b487bc 100644 --- a/php/README.md +++ b/php/README.md @@ -25,3 +25,6 @@ * main 堆的基本操作,堆排序 * findmiddle 动态数据流求中位数 * topn 动态数据流求top k +#### 24_tree +* main 二叉树的基本操作 前中后序遍历 +* levelOrder 二叉树的层级遍历 From 15d1990a06c99a1117b8b53ca6f27ea5d3bbf41a Mon Sep 17 00:00:00 2001 From: damianzhenxiaozhi <8603583+damianzhenxiaozhi@users.noreply.github.com> Date: Fri, 27 Sep 2019 15:53:55 +0800 Subject: [PATCH 18/33] should remove node in list and hash table both MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除一个缓存元素时,除了删除链表中的节点,也要删除散列表中的节点。 --- java/20_hashtable/LRUBaseHashTable.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/20_hashtable/LRUBaseHashTable.java b/java/20_hashtable/LRUBaseHashTable.java index 8aeb8eb0..af6e1744 100644 --- a/java/20_hashtable/LRUBaseHashTable.java +++ b/java/20_hashtable/LRUBaseHashTable.java @@ -182,6 +182,7 @@ public void remove(K key) { } removeNode(node); length--; + table.remove(node.key); } private void printAll() { @@ -192,4 +193,4 @@ private void printAll() { } System.out.println(); } -} \ No newline at end of file +} From d4eac2fdcdfefa70e5a3a0e5eaa71a64fb5193d8 Mon Sep 17 00:00:00 2001 From: damianzhenxiaozhi <8603583+damianzhenxiaozhi@users.noreply.github.com> Date: Fri, 27 Sep 2019 18:31:22 +0800 Subject: [PATCH 19/33] removing all e in bucket, "use" should decrease MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除槽中所有元素后,hash表占用变量use需要减1。 --- java/18_hashtable/HashTable.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/18_hashtable/HashTable.java b/java/18_hashtable/HashTable.java index 9db7c7f1..c2df5793 100644 --- a/java/18_hashtable/HashTable.java +++ b/java/18_hashtable/HashTable.java @@ -142,12 +142,14 @@ public void remove(K key) { } Entry pre; + Entry headNode = table[index]; do { pre = e; e = e.next; if (key == e.key) { pre.next = e.next; size--; + if (headNode.next == null) use--; return; } } while (e.next != null); From fcffdacfcb11752743994456125d99b00d5634f1 Mon Sep 17 00:00:00 2001 From: Miles Date: Thu, 10 Oct 2019 17:40:13 +0800 Subject: [PATCH 20/33] add javascript bucketSort --- javascript/13_sorts/bucketSort.js | 70 +++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 javascript/13_sorts/bucketSort.js diff --git a/javascript/13_sorts/bucketSort.js b/javascript/13_sorts/bucketSort.js new file mode 100644 index 00000000..d53d1b52 --- /dev/null +++ b/javascript/13_sorts/bucketSort.js @@ -0,0 +1,70 @@ +// 思路: +// 将数组中的数据,按桶进行划分,将相邻的数据划分在同一个桶中 +// 每个桶用插入排序算法(或者快速排序)进行排序 +// 最后整合每个桶中的数据 + +function bucketSort(array, bucketSize = 5) { + if (array.length < 2) { + return array + } + const buckets = createBuckets(array, bucketSize) + return sortBuckets(buckets) +} + +function createBuckets(array, bucketSize) { + let minValue = array[0] + let maxValue = array[0] + // 遍历数组,找到数组最小值与数组最大值 + for (let i = 1; i < array.length; i++) { + if (array[i] < minValue) { + minValue = array[i] + } else if (array[i] > maxValue) { + maxValue = array[i] + } + } + // 根据最小值、最大值、桶的大小,计算得到桶的个数 + const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1 + // 建立一个二维数组,将桶放入buckets中 + const buckets = [] + for (let i = 0; i < bucketCount; i++) { + buckets[i] = [] + } + // 计算每一个值应该放在哪一个桶中 + for (let i = 0; i < array.length; i++) { + const bucketIndex = Math.floor((array[i] - minValue) / bucketSize) + buckets[bucketIndex].push(array[i]) + } + return buckets +} + +function sortBuckets(buckets) { + const sortedArray = [] + for (let i = 0; i < buckets.length; i++) { + if (buckets[i] != null) { + insertionSort(buckets[i]) + sortedArray.push(...buckets[i]) + } + } + return sortedArray +} + +// 插入排序 +function insertionSort(array) { + const { length } = array + if (length <= 1) return + + for (let i = 1; i < length; i++) { + let value = array[i] + let j = i - 1 + + while (j >= 0) { + if (array[j] > value) { + array[j + 1] = array[j] // 移动 + j-- + } else { + break + } + } + array[j + 1] = value // 插入数据 + } +} From b362685e16e96e527e3a2681cfcbe0b5e8a8c0a0 Mon Sep 17 00:00:00 2001 From: Miles Date: Thu, 10 Oct 2019 18:17:08 +0800 Subject: [PATCH 21/33] add javascript counting sort --- javascript/13_sorts/countingSort.js | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 javascript/13_sorts/countingSort.js diff --git a/javascript/13_sorts/countingSort.js b/javascript/13_sorts/countingSort.js new file mode 100644 index 00000000..d892f669 --- /dev/null +++ b/javascript/13_sorts/countingSort.js @@ -0,0 +1,38 @@ +const countingSort = array => { + if (array.length <= 1) return + + const max = findMaxValue(array) + const counts = new Array(max + 1) + + // 计算每个元素的个数,放入到counts桶中 + // counts下标是元素,值是元素个数 + array.forEach(element => { + if (!counts[element]) { + counts[element] = 0 + } + counts[element]++ + }) + + // counts下标是元素,值是元素个数 + // 例如: array: [6, 4, 3, 1], counts: [empty, 1, empty, 1, 1, empty, 1] + // i是元素, count是元素个数 + let sortedIndex = 0 + counts.forEach((count, i) => { + while (count > 0) { + array[sortedIndex] = i + sortedIndex++ + count-- + } + }) + // return array +} + +function findMaxValue(array) { + let max = array[0] + for (let i = 1; i < array.length; i++) { + if (array[i] > max) { + max = array[i] + } + } + return max +} From 4d5f41010e882ea557cb9ade0ea4a5f21929272c Mon Sep 17 00:00:00 2001 From: zhangguangying <786781353@qq.com> Date: Fri, 11 Oct 2019 10:42:16 +0800 Subject: [PATCH 22/33] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=89=8D=E7=BD=AE?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/06_linkedlist/SingleLinkedList.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/php/06_linkedlist/SingleLinkedList.php b/php/06_linkedlist/SingleLinkedList.php index 222f638a..994d49f4 100644 --- a/php/06_linkedlist/SingleLinkedList.php +++ b/php/06_linkedlist/SingleLinkedList.php @@ -86,6 +86,9 @@ public function delete(SingleLinkedListNode $node) // 获取待删除节点的前置节点 $preNode = $this->getPreNode($node); + if (empty($preNode)) { + return false; + } // 修改指针指向 $preNode->next = $node->next; @@ -121,7 +124,7 @@ public function getNodeByIndex($index) * * @param SingleLinkedListNode $node * - * @return SingleLinkedListNode|bool + * @return SingleLinkedListNode|bool|null */ public function getPreNode(SingleLinkedListNode $node) { @@ -133,7 +136,10 @@ public function getPreNode(SingleLinkedListNode $node) $preNode = $this->head; // 遍历找到前置节点 要用全等判断是否是同一个对象 // http://php.net/manual/zh/language.oop5.object-comparison.php - while ($curNode !== $node && $curNode != null) { + while ($curNode !== $node) { + if ($curNode == null) { + return null; + } $preNode = $curNode; $curNode = $curNode->next; } From 082960631108c8b0f3257176cc07281b94969c05 Mon Sep 17 00:00:00 2001 From: liurui Date: Thu, 24 Oct 2019 10:53:31 +0800 Subject: [PATCH 23/33] =?UTF-8?q?=E5=9B=9E=E6=96=87=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/06_linkedlist/SinglyLinkedList.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/java/06_linkedlist/SinglyLinkedList.java b/java/06_linkedlist/SinglyLinkedList.java index 1a8b0f87..fd7453d6 100644 --- a/java/06_linkedlist/SinglyLinkedList.java +++ b/java/06_linkedlist/SinglyLinkedList.java @@ -172,6 +172,7 @@ public boolean TFResult(Node left, Node right){ Node l = left; Node r = right; + boolean flag=true; System.out.println("left_:"+l.data); System.out.println("right_:"+r.data); while(l != null && r != null){ @@ -180,18 +181,20 @@ public boolean TFResult(Node left, Node right){ r = r.next; continue; }else{ + flag=false; break; } } System.out.println("什么结果"); - if (l==null && r==null){ + return flag; + /* if (l==null && r==null){ System.out.println("什么结果"); return true; }else{ return false; - } + }*/ } // 判断是否为回文 From 8dde3c4933999f38f119fef2bd8ba6abf66bcf8e Mon Sep 17 00:00:00 2001 From: lidebo Date: Fri, 25 Oct 2019 17:35:26 +0800 Subject: [PATCH 24/33] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B7=B3=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E4=BE=BF=E4=BA=8E=E5=AD=A6=E4=B9=A0=E7=90=86=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/12_sorts/Sorts.java | 395 ++++++++++++++++++++++++++++++++ java/17_skiplist/SkipList2.java | 307 +++++++++++++++++++++++++ java/30_graph/Graph.java | 119 ++++++++++ 3 files changed, 821 insertions(+) create mode 100644 java/12_sorts/Sorts.java create mode 100644 java/17_skiplist/SkipList2.java create mode 100644 java/30_graph/Graph.java diff --git a/java/12_sorts/Sorts.java b/java/12_sorts/Sorts.java new file mode 100644 index 00000000..8f0666a7 --- /dev/null +++ b/java/12_sorts/Sorts.java @@ -0,0 +1,395 @@ +package com.study.sort; + +import java.util.Arrays; + +/** + * 冒泡,选择,插入,快速,归并 + * + * @author ldb + * @date 2019-10-08 16:09 + */ +public class Sorts { + + /** + * 冒泡排序 + * + * @param arr + */ + public static void bubbleSort(int[] arr) { + for (int i = 0; i < arr.length; i++) { + for (int j = 0; j < arr.length - 1 - i; j++) { + if (arr[j] > arr[j + 1]) { + int temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } + } + + /** + * 优化冒泡排序 + * + * @param arr + */ + public static void bubbleSort2(int[] arr) { + for (int i = 0; i < arr.length - 1; i++) { + boolean flag = true; + for (int j = 0; j < arr.length - 1 - i; j++) { + if (arr[j] > arr[j + 1]) { + int temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + flag = false; + } + } + if (flag) { + break; + } + } + } + + /** + * 插入排序 + * + * @param arr + */ + public static void insertSort(int[] arr) { + for (int i = 1; i < arr.length; i++) { + int val = arr[i]; + int index = i - 1; + while (index >= 0 && arr[index] > val) { + arr[index + 1] = arr[index]; + index--; + } + arr[index + 1] = val; + } + } + + /** + * 插入排序 + * + * @param arr + * @param n 表示数组有用大小 + */ + public static void insertSort(int[] arr, int n) { + for (int i = 1; i < n; i++) { + int val = arr[i]; + int index = i - 1; + while (index >= 0 && arr[index] > val) { + arr[index + 1] = arr[index]; + index--; + } + arr[index + 1] = val; + } + } + + /** + * 选择排序 + * + * @param arr + */ + public static void selectSort(int[] arr) { + + for (int i = 0; i < arr.length - 1; i++) { + int minIndex = i; + for (int j = i + 1; j < arr.length; j++) { + if (arr[minIndex] > arr[j]) { + minIndex = j; + } + } + // 交换 + int temp = arr[i]; + arr[i] = arr[minIndex]; + arr[minIndex] = temp; + } + } + + /** + * 归并排序 + * + * @param arr + */ + public static void mergeSort(int[] arr, int left, int right) { + if (left >= right) { + return; + } + int q = (left + right) / 2; + mergeSort(arr, left, q); + mergeSort(arr, q + 1, right); + merge2(arr, left, q, right); + + } + + private static void merge2(int[] arr, int left, int q, int right) { + int[] leftArr = new int[q - left + 2]; + int[] rightArr = new int[right - q + 1]; + + for (int i = 0; i <= q - left; i++) { + leftArr[i] = arr[left + i]; + } + // 第一个数组添加哨兵(最大值) + leftArr[q - left + 1] = Integer.MAX_VALUE; + + for (int i = 0; i < right - q; i++) { + rightArr[i] = arr[q + 1 + i]; + } + // 第二个数组添加哨兵(最大值) + rightArr[right - q] = Integer.MAX_VALUE; + + int i = 0; + int j = 0; + int k = left; + while (k <= right) { + // 当左边数组到达哨兵值时,i不再增加,直到右边数组读取完剩余值,同理右边数组也一样 + if (leftArr[i] <= rightArr[j]) { + arr[k++] = leftArr[i++]; + } else { + arr[k++] = rightArr[j++]; + } + } + } + + private static void merge(int[] arr, int left, int q, int right) { + int i = left; + int j = q + 1; + int k = 0; + int[] tmp = new int[right - left + 1]; + while (i <= q && j <= right) { + if (arr[i] <= arr[j]) { + tmp[k++] = arr[i++]; + } else { + tmp[k++] = arr[j++]; + } + } + int start = i; + int end = q; + if (j <= right) { + start = j; + end = right; + } + while (start <= end) { + tmp[k++] = arr[start++]; + } + for (int l = 0; l <= right - left; l++) { + arr[l + left] = tmp[l]; + } + + } + + /** + * 快速排序 + * + * @param arr + */ + public static void quickSort(int[] arr, int left, int right) { + if (left >= right) { + return; + } + int q = partition2(arr, left, right); + quickSort(arr, left, q - 1); + quickSort(arr, q + 1, right); + } + + private static int partition(int[] arr, int left, int right) { + int pivot = arr[right]; + int i = left; + for (int j = left; j < right; j++) { + if (arr[j] < pivot) { + if (i == j) { + ++i; + } else { + int tmp = arr[i]; + arr[i++] = arr[j]; + arr[j] = tmp; + } + } + } + int tmp = arr[i]; + arr[i] = arr[right]; + arr[right] = tmp; + return i; + } + + private static int partition2(int[] arr, int left, int right) { + // 三数取中法 , 随机数在这里写 + int middle = (left + right) / 2; + int pivot = arr[middle]; + // 交换到最右边 + int val = arr[right]; + arr[right] = pivot; + arr[middle] = val; + int i = left; + for (int j = left; j < right; j++) { + if (arr[j] < pivot) { + if (i == j) { + ++i; + } else { + int tmp = arr[i]; + arr[i++] = arr[j]; + arr[j] = tmp; + } + } + } + int tmp = arr[i]; + arr[i] = arr[right]; + arr[right] = tmp; + return i; + } + + /** + * 三向切分快速排序 + * + * @param arr + * @param left + * @param right + * @return + */ + private static void quickSort3(int[] arr, int left, int right) { + if (left >= right) { + return; + } + int l = left; + int k = left + 1; + int r = right; + int pivot = arr[l]; + + while (k <= r) { + if (arr[k] < pivot) { + int tmp = arr[l]; + arr[l] = arr[k]; + arr[k] = tmp; + l++; + k++; + } else if (arr[k] == pivot) { + k++; + } else { + if (arr[r] > pivot) { + r--; + } else if (arr[r] == pivot) { + int tmp = arr[k]; + arr[k] = arr[r]; + arr[r] = tmp; + k++; + r--; + } else { + int tmp = arr[l]; + arr[l] = arr[r]; + arr[r] = arr[k]; + arr[k] = tmp; + l++; + k++; + r--; + } + } + } + + quickSort(arr, left, l - 1); + quickSort(arr, r + 1, right); + } + + /** + * 双轴快速排序 + * + * @param arr + * @param left + * @param right + */ + private static void quickSort4(int[] arr, int left, int right) { + if (left >= right) { + return; + } + int l = left; + int k = left + 1; + int r = right; + // 判断pivot1 与 pivot2 大小 + if (arr[l] > arr[r]) { + int tmp = arr[l]; + arr[l] = arr[r]; + arr[r] = tmp; + } + int pivot1 = arr[l]; + int pivot2 = arr[r]; + + while (k < r) { + if (arr[k] < pivot1) { + l++; + if (l != k) { + int tmp = arr[l]; + arr[l] = arr[k]; + arr[k] = tmp; + } + k++; + } else if (arr[k] >= pivot1 && arr[k] <= pivot2) { + k++; + } else { + --r; + if (arr[r] > pivot2) { + } else if (arr[r] >= pivot1 && arr[r] <= pivot2) { + int tmp = arr[k]; + arr[k] = arr[r]; + arr[r] = tmp; + k++; + } else { + l++; + int tmp = arr[l]; + arr[l] = arr[r]; + arr[r] = arr[k]; + arr[k] = tmp; + k++; + } + } + } + + // 交换pivot1 和 pivot2 + arr[left] = arr[l]; + arr[l] = pivot1; + arr[right] = arr[r]; + arr[r] = pivot2; + + quickSort(arr, left, l - 1); + quickSort(arr, l + 1, r - 1); + quickSort(arr, r + 1, right); + } + + /** + * O(n) 时间复杂度内求无序数组中的第 K 大元素。比如, 4 , 2 , 5 , 12 , 3 这样一组数据,第 3 大元素就是 4 。 + * + * @param arr + */ + public static int sort(int[] arr, int l, int r, int k) { + if (l >= r) { + return 0; + } + int p = partition(arr, l, r); + if ((p + 1) == k) { + return arr[p]; + } else if ((p + 1) < k) { + return sort(arr, p + 1, r, k); + } else { + return sort(arr, l, p - 1, k); + } + } + + public static void main(String[] args) { + int[] arr = {2, 1, 5, 6, 8, 4, 12, 11, 13, 15, 7, 9, 0, -1}; +// bubbleSort(arr); +// bubbleSort2(arr); +// selectSort(arr); +// mergeSort(arr, 0, arr.length - 1); +// quickSort4(arr, 0, arr.length - 1); + + Arrays.sort(arr); + print(arr); + + } + + public static void print(int[] arr) { + for (int i : arr) { + System.out.print(i + " "); + } + System.out.println(); + } + + +} diff --git a/java/17_skiplist/SkipList2.java b/java/17_skiplist/SkipList2.java new file mode 100644 index 00000000..ebf7e58f --- /dev/null +++ b/java/17_skiplist/SkipList2.java @@ -0,0 +1,307 @@ +package com.study.skiplist; + +import java.util.Random; + +/** + * 1,跳表的一种实现方法,用于练习。跳表中存储的是正整数,并且存储的是不重复的。 + * 2,本类是参考作者zheng ,自己学习,优化了添加方法 + * 3,看完这个,我觉得再看ConcurrentSkipListMap 源码,会有很大收获 + * Author:ldb + */ +public class SkipList2 { + + private static final int MAX_LEVEL = 16; + private int levelCount = 1; + + /** + * 带头链表 + */ + private Node head = new Node(MAX_LEVEL); + private Random r = new Random(); + + public Node find(int value) { + Node p = head; + // 从最大层开始查找,找到前一节点,通过--i,移动到下层再开始查找 + for (int i = levelCount - 1; i >= 0; --i) { + while (p.forwards[i] != null && p.forwards[i].data < value) { + // 找到前一节点 + p = p.forwards[i]; + } + } + + if (p.forwards[0] != null && p.forwards[0].data == value) { + return p.forwards[0]; + } else { + return null; + } + } + + /** + * 优化了作者zheng的插入方法 + * + * @param value 值 + */ + public void insert(int value) { + int level = head.forwards[0] == null ? 1 : randomLevel(); + // 每次只增加一层,如果条件满足 + if (level > levelCount) { + level = ++levelCount; + } + Node newNode = new Node(level); + newNode.data = value; + Node update[] = new Node[level]; + for (int i = 0; i < level; ++i) { + update[i] = head; + } + + Node p = head; + // 从最大层开始查找,找到前一节点,通过--i,移动到下层再开始查找 + for (int i = levelCount - 1; i >= 0; --i) { + while (p.forwards[i] != null && p.forwards[i].data < value) { + // 找到前一节点 + p = p.forwards[i]; + } + // levelCount 会 > level,所以加上判断 + if (level > i) { + update[i] = p; + } + + } + for (int i = 0; i < level; ++i) { + newNode.forwards[i] = update[i].forwards[i]; + update[i].forwards[i] = newNode; + } + + } + + /** + * 优化了作者zheng的插入方法2 + * + * @param value 值 + */ + public void insert2(int value) { + int level = head.forwards[0] == null ? 1 : randomLevel(); + // 每次只增加一层,如果条件满足 + if (level > levelCount) { + level = ++levelCount; + } + Node newNode = new Node(level); + newNode.data = value; + Node p = head; + // 从最大层开始查找,找到前一节点,通过--i,移动到下层再开始查找 + for (int i = levelCount - 1; i >= 0; --i) { + while (p.forwards[i] != null && p.forwards[i].data < value) { + // 找到前一节点 + p = p.forwards[i]; + } + // levelCount 会 > level,所以加上判断 + if (level > i) { + if (p.forwards[i] == null) { + p.forwards[i] = newNode; + } else { + Node next = p.forwards[i]; + p.forwards[i] = newNode; + newNode.forwards[i] = next; + } + } + + } + + } + + /** + * 作者zheng的插入方法,未优化前,优化后参见上面insert() + * + * @param value + * @param level 0 表示随机层数,不为0,表示指定层数,指定层数 + * 可以让每次打印结果不变动,这里是为了便于学习理解 + */ + public void insert(int value, int level) { + // 随机一个层数 + if (level == 0) { + level = randomLevel(); + } + // 创建新节点 + Node newNode = new Node(level); + newNode.data = value; + // 表示从最大层到低层,都要有节点数据 + newNode.maxLevel = level; + // 记录要更新的层数,表示新节点要更新到哪几层 + Node update[] = new Node[level]; + for (int i = 0; i < level; ++i) { + update[i] = head; + } + + /** + * + * 1,说明:层是从下到上的,这里最下层编号是0,最上层编号是15 + * 2,这里没有从已有数据最大层(编号最大)开始找,(而是随机层的最大层)导致有些问题。 + * 如果数据量为1亿,随机level=1 ,那么插入时间复杂度为O(n) + */ + Node p = head; + for (int i = level - 1; i >= 0; --i) { + while (p.forwards[i] != null && p.forwards[i].data < value) { + p = p.forwards[i]; + } + // 这里update[i]表示当前层节点的前一节点,因为要找到前一节点,才好插入数据 + update[i] = p; + } + + // 将每一层节点和后面节点关联 + for (int i = 0; i < level; ++i) { + // 记录当前层节点后面节点指针 + newNode.forwards[i] = update[i].forwards[i]; + // 前一个节点的指针,指向当前节点 + update[i].forwards[i] = newNode; + } + + // 更新层高 + if (levelCount < level) levelCount = level; + } + + public void delete(int value) { + Node[] update = new Node[levelCount]; + Node p = head; + for (int i = levelCount - 1; i >= 0; --i) { + while (p.forwards[i] != null && p.forwards[i].data < value) { + p = p.forwards[i]; + } + update[i] = p; + } + + if (p.forwards[0] != null && p.forwards[0].data == value) { + for (int i = levelCount - 1; i >= 0; --i) { + if (update[i].forwards[i] != null && update[i].forwards[i].data == value) { + update[i].forwards[i] = update[i].forwards[i].forwards[i]; + } + } + } + } + + /** + * 随机 level 次,如果是奇数层数 +1,防止伪随机 + * + * @return + */ + private int randomLevel() { + int level = 1; + for (int i = 1; i < MAX_LEVEL; ++i) { + if (r.nextInt() % 2 == 1) { + level++; + } + } + return level; + } + + /** + * 打印每个节点数据和最大层数 + */ + public void printAll() { + Node p = head; + while (p.forwards[0] != null) { + System.out.print(p.forwards[0] + " "); + p = p.forwards[0]; + } + System.out.println(); + } + + /** + * 打印所有数据 + */ + public void printAll_beautiful() { + Node p = head; + Node[] c = p.forwards; + Node[] d = c; + int maxLevel = c.length; + for (int i = maxLevel - 1; i >= 0; i--) { + do { + System.out.print((d[i] != null ? d[i].data : null) + ":" + i + "-------"); + } while (d[i] != null && (d = d[i].forwards)[i] != null); + System.out.println(); + d = c; + } + } + + /** + * 跳表的节点,每个节点记录了当前节点数据和所在层数数据 + */ + public class Node { + private int data = -1; + /** + * 表示当前节点位置的下一个节点所有层的数据,从上层切换到下层,就是数组下标-1, + * forwards[3]表示当前节点在第三层的下一个节点。 + */ + private Node forwards[]; + + /** + * 这个值其实可以不用,看优化insert() + */ + private int maxLevel = 0; + + public Node(int level) { + forwards = new Node[level]; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{ data: "); + builder.append(data); + builder.append("; levels: "); + builder.append(maxLevel); + builder.append(" }"); + return builder.toString(); + } + } + + public static void main(String[] args) { + SkipList2 list = new SkipList2(); + list.insert(1, 3); + list.insert(2, 3); + list.insert(3, 2); + list.insert(4, 4); + list.insert(5, 10); + list.insert(6, 4); + list.insert(8, 5); + list.insert(7, 4); + list.printAll_beautiful(); + list.printAll(); + /** + * 结果如下: + * null:15------- + * null:14------- + * null:13------- + * null:12------- + * null:11------- + * null:10------- + * 5:9------- + * 5:8------- + * 5:7------- + * 5:6------- + * 5:5------- + * 5:4------- 8:4------- + * 4:3-------5:3-------6:3-------7:3-------8:3------- + * 1:2-------2:2------- 4:2-------5:2-------6:2-------7:2-------8:2------- + * 1:1-------2:1-------3:1-------4:1-------5:1-------6:1-------7:1-------8:1------- + * 1:0-------2:0-------3:0-------4:0-------5:0-------6:0-------7:0-------8:0------- + * { data: 1; levels: 3 } { data: 2; levels: 3 } { data: 3; levels: 2 } { data: 4; levels: 4 } + * { data: 5; levels: 10 } { data: 6; levels: 4 } { data: 7; levels: 4 } { data: 8; levels: 5 } + */ + // 优化后insert() + + SkipList2 list2 = new SkipList2(); + list2.insert2(1); + list2.insert2(2); + list2.insert2(6); + list2.insert2(7); + list2.insert2(8); + list2.insert2(3); + list2.insert2(4); + list2.insert2(5); + System.out.println(); + list2.printAll_beautiful(); + + + } + +} diff --git a/java/30_graph/Graph.java b/java/30_graph/Graph.java new file mode 100644 index 00000000..74e6d670 --- /dev/null +++ b/java/30_graph/Graph.java @@ -0,0 +1,119 @@ +package com.study.graph; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * @author ldb + * @date 2019-10-23 15:10 + */ +public class Graph { + private int v; + private LinkedList adj[]; // 邻接表 + + public Graph(int v) { + this.v = v; + adj = new LinkedList[v]; + for (int i = 0; i < v; ++i) { + adj[i] = new LinkedList<>(); + } + } + + /** + * 添加边 + * + * @param s 顶点 + * @param t 顶点 + */ + public void addEdge(int s, int t) { // 无向图一条边存两次 + adj[s].add(t); + adj[t].add(s); + + } + + public void bfs(int s, int t) { + if (s == t) return; + // visited是用来记录已经被访问的顶点,用来避免顶点被重复访问。 + boolean[] visited = new boolean[v]; + visited[s] = true; + // queue是一个队列,用来存储已经被访问、但相连的顶点还没有被访问的顶点。 + Queue queue = new LinkedList<>(); + queue.add(s); + // prev用来记录搜索路径。 + int[] prev = new int[v]; + for (int i = 0; i < v; ++i) { + prev[i] = -1; + } + while (queue.size() != 0) { + int w = queue.poll(); + for (int i = 0; i < adj[w].size(); ++i) { + int q = adj[w].get(i); + if (!visited[q]) { + prev[q] = w; + if (q == t) { + print(prev, s, t); + return; + } + visited[q] = true; + queue.add(q); + } + } + } + } + + private void print(int[] prev, int s, int t) { // 递归打印 s->t 的路径 + if (prev[t] != -1 && t != s) { + print(prev, s, prev[t]); + } + System.out.print(t + " "); + } + + public static void main(String[] args) { + Graph graph = new Graph(8); + graph.addEdge(0,1); + graph.addEdge(0,3); + graph.addEdge(1,2); + graph.addEdge(1,4); + graph.addEdge(2,5); + graph.addEdge(4,5); + graph.addEdge(4,6); + graph.addEdge(5,7); + graph.addEdge(6,7); +// graph.bfs(0,6); + + // 深度优先 + graph.dfs(0, 6); + + } + + boolean found = false; // 全局变量或者类成员变量 + + public void dfs(int s, int t) { + found = false; + boolean[] visited = new boolean[v]; + int[] prev = new int[v]; + for (int i = 0; i < v; ++i) { + prev[i] = -1; + } + recurDfs(s, t, visited, prev); + print(prev, s, t); + } + + private void recurDfs(int w, int t, boolean[] visited, int[] prev) { + if (found == true) return; + visited[w] = true; + if (w == t) { + found = true; + return; + } + for (int i = 0; i < adj[w].size(); ++i) { + int q = adj[w].get(i); + if (!visited[q]) { + prev[q] = w; + recurDfs(q, t, visited, prev); + } + } + } +} + + From 16ed6a71e7dd48d46c923ed602329a12009e499e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=80=9D=E4=B9=9F?= Date: Sat, 2 Nov 2019 15:14:51 +0800 Subject: [PATCH 25/33] =?UTF-8?q?=E9=81=BF=E5=85=8Delem=E7=9A=84next?= =?UTF-8?q?=E4=B8=8D=E4=B8=BA=E7=A9=BA=E5=AF=BC=E8=87=B4=E7=9A=84=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E4=B8=80=E4=B8=AA=E9=93=BE=E8=A1=A8=E8=80=8C=E9=9D=9E?= =?UTF-8?q?=E7=BB=93=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- c-cpp/06_linkedlist/single_list.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/c-cpp/06_linkedlist/single_list.c b/c-cpp/06_linkedlist/single_list.c index a267595e..82ae084d 100644 --- a/c-cpp/06_linkedlist/single_list.c +++ b/c-cpp/06_linkedlist/single_list.c @@ -31,8 +31,7 @@ void insert(struct single_list **prev, struct single_list *elem) if (!prev) return; - if (*prev) - elem->next = *prev; + elem->next = *prev; *prev = elem; } From d123bbe27986b0a14648e533d74ae0076b03dfa9 Mon Sep 17 00:00:00 2001 From: ROVAST Date: Wed, 6 Nov 2019 16:41:57 +0800 Subject: [PATCH 26/33] fix spell mistake null To NULL --- c-cpp/06_linkedlist/single_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c-cpp/06_linkedlist/single_list.c b/c-cpp/06_linkedlist/single_list.c index a267595e..32ea0cc9 100644 --- a/c-cpp/06_linkedlist/single_list.c +++ b/c-cpp/06_linkedlist/single_list.c @@ -47,7 +47,7 @@ struct single_list* del(struct single_list **prev) if (!prev) return NULL; - if (*prev == null) + if (*prev == NULL) return NULL; tmp = *prev; *prev = (*prev)->next; From ef192f002f0ae05812fead6bfaddda3d912894f8 Mon Sep 17 00:00:00 2001 From: Zhangfeng Date: Wed, 6 Nov 2019 17:39:38 +0800 Subject: [PATCH 27/33] Update GenericArray.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit set 和 get 方法中 index 索引范围为:index >=0 && index < size --- java/05_array/GenericArray.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/05_array/GenericArray.java b/java/05_array/GenericArray.java index 631a1bae..489d3567 100644 --- a/java/05_array/GenericArray.java +++ b/java/05_array/GenericArray.java @@ -63,7 +63,7 @@ public int find(T e) { // 在 index 位置,插入元素e, 时间复杂度 O(m+n) public void add(int index, T e) { - checkIndex(index); + checkIndexForAdd(index); // 如果当前元素个数等于数组容量,则将数组扩容为原来的2倍 if (size == data.length) { resize(2 * data.length); @@ -88,7 +88,7 @@ public void addLast(T e) { // 删除 index 位置的元素,并返回 public T remove(int index) { - checkIndexForRemove(index); + checkIndex(index); T ret = data[index]; for (int i = index + 1; i < size; i++) { @@ -150,14 +150,14 @@ private void resize(int capacity) { } private void checkIndex(int index) { - if (index < 0 || index > size) { - throw new IllegalArgumentException("Add failed! Require index >=0 and index <= size."); + if (index < 0 || index >= size) { + throw new IllegalArgumentException("Add failed! Require index >=0 and index < size."); } } - private void checkIndexForRemove(int index) { - if(index < 0 || index >= size) { - throw new IllegalArgumentException("remove failed! Require index >=0 and index < size."); + private void checkIndexForAdd(int index) { + if(index < 0 || index > size) { + throw new IllegalArgumentException("remove failed! Require index >=0 and index <= size."); } } -} \ No newline at end of file +} From 6c02e93b87d530aefdb764f1c1d589402f174105 Mon Sep 17 00:00:00 2001 From: ares Date: Mon, 11 Nov 2019 19:54:41 +0800 Subject: [PATCH 28/33] =?UTF-8?q?=E4=BD=BF=E5=85=B6=E6=88=90=E4=B8=BA?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E7=A8=B3=E5=AE=9A=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go/12_sorts/MergeSort.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/12_sorts/MergeSort.go b/go/12_sorts/MergeSort.go index 99babd41..71340d08 100644 --- a/go/12_sorts/MergeSort.go +++ b/go/12_sorts/MergeSort.go @@ -27,7 +27,7 @@ func merge(arr []int, start, mid, end int) { j := mid + 1 k := 0 for ; i <= mid && j <= end; k++ { - if arr[i] < arr[j] { + if arr[i] <= arr[j] { tmpArr[k] = arr[i] i++ } else { From d90ba18823e141907a88ddd1b1a533296e7a8a49 Mon Sep 17 00:00:00 2001 From: "Chih Hong, Chen" Date: Tue, 12 Nov 2019 13:50:17 +0800 Subject: [PATCH 29/33] [golang] Simplify stack IsEmpty function IsEmpty function can be simplified to one line, which is clearer. --- go/08_stack/StackBasedOnLinkedList.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/go/08_stack/StackBasedOnLinkedList.go b/go/08_stack/StackBasedOnLinkedList.go index ef4fef40..4101c9ed 100644 --- a/go/08_stack/StackBasedOnLinkedList.go +++ b/go/08_stack/StackBasedOnLinkedList.go @@ -20,10 +20,7 @@ func NewLinkedListStack() *LinkedListStack { } func (this *LinkedListStack) IsEmpty() bool { - if this.topNode == nil { - return true - } - return false + return this.topNode == nil } func (this *LinkedListStack) Push(v interface{}) { From 905a58fe9966b8d21410fc6045575a5d4a908ffe Mon Sep 17 00:00:00 2001 From: ares Date: Thu, 14 Nov 2019 16:14:46 +0800 Subject: [PATCH 30/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9golang=E7=89=88Counting?= =?UTF-8?q?Sort,=20=E4=BF=AE=E6=94=B9=E4=B8=BA=E4=BB=8E=E5=90=8E=E5=90=91?= =?UTF-8?q?=E5=89=8D=E9=81=8D=E5=8E=86,=20=E4=BD=BF=E5=85=B6=E6=88=90?= =?UTF-8?q?=E4=B8=BA=E7=A8=B3=E5=AE=9A=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go/14_sorts/CountingSort.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/14_sorts/CountingSort.go b/go/14_sorts/CountingSort.go index 834a2c1a..0fbb2f70 100644 --- a/go/14_sorts/CountingSort.go +++ b/go/14_sorts/CountingSort.go @@ -23,7 +23,7 @@ func CountingSort(a []int, n int) { } r := make([]int, n) - for i := range a { + for i := n - 1; i >= 0; i-- { index := c[a[i]] - 1 r[index] = a[i] c[a[i]]-- From 185fcfb62a2c3e7a685f5fdc6d4516f310999948 Mon Sep 17 00:00:00 2001 From: wangzheng0822 Date: Tue, 28 Jan 2020 20:48:04 +0800 Subject: [PATCH 31/33] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ceae59ef..549ca77c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 数据结构和算法必知必会的50个代码实现 -### 微信搜索我的公众号“小争哥”,或者微信扫描下面二维码, 获取更多压箱底的干货分享 -### 前Google工程师,5万+人跟着学的《数据结构和算法之美》专栏作者 +### 微信搜索我的公众号“小争哥”,或者微信扫描下面二维码, 回复”算法“或”设计模式“获取更多学习资料。 +### 前Google工程师,10万人跟着学的《数据结构和算法之美》《设计模式之美》专栏作者 ![t2](https://github.com/wangzheng0822/markdownphotos/blob/master/pics/qrcode_for_gh_9b0e7afdff20_258.jpg) ## 数组 From cc245cd3152176002b8803fda78778bff1362968 Mon Sep 17 00:00:00 2001 From: wangzheng0822 Date: Tue, 28 Jan 2020 20:49:07 +0800 Subject: [PATCH 32/33] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 549ca77c..bdf69908 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # 数据结构和算法必知必会的50个代码实现 -### 微信搜索我的公众号“小争哥”,或者微信扫描下面二维码, 回复”算法“或”设计模式“获取更多学习资料。 +### 微信搜索我的公众号“小争哥”,或者微信扫描下面二维码关注 +### 关注微信公众号,回复”算法“或”设计模式“获取更多学习资料。 ### 前Google工程师,10万人跟着学的《数据结构和算法之美》《设计模式之美》专栏作者 ![t2](https://github.com/wangzheng0822/markdownphotos/blob/master/pics/qrcode_for_gh_9b0e7afdff20_258.jpg) From b2c1228ff915287ad7ebeae4355fa26854ea1557 Mon Sep 17 00:00:00 2001 From: wangzheng0822 Date: Tue, 17 Nov 2020 19:47:08 +0800 Subject: [PATCH 33/33] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bdf69908..107cb375 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 数据结构和算法必知必会的50个代码实现 ### 微信搜索我的公众号“小争哥”,或者微信扫描下面二维码关注 -### 关注微信公众号,回复”算法“或”设计模式“获取更多学习资料。 +### 关注微信公众号,回复”PDF“获取独家算法资料。 ### 前Google工程师,10万人跟着学的《数据结构和算法之美》《设计模式之美》专栏作者 ![t2](https://github.com/wangzheng0822/markdownphotos/blob/master/pics/qrcode_for_gh_9b0e7afdff20_258.jpg)