fix(guide): simplify directory structure

This commit is contained in:
Mrugesh Mohapatra
2018-10-16 21:26:13 +05:30
parent f989c28c52
commit da0df12ab7
35752 changed files with 0 additions and 317652 deletions

View File

@@ -0,0 +1,154 @@
---
title: Bubble Sort
localeTitle: 冒泡排序
---
## 冒泡排序
冒泡排序是最简单的排序算法,如果它们的顺序错误,可以反复交换相邻的元素。
与诸如快速排序的算法相比这是一种非常慢的排序算法具有最坏情况复杂度On ^ 2。然而权衡的是冒泡排序是从头开始实施的最简单的排序算法之一。
### 例:
#### 第一关:
5 1 4 2 8 - >1 5 4 2 8这里算法比较前两个元素并从5> 1开始交换。
1 5 4 2 8 - >1 4 5 2 8从5> 4开始交换
1 4 5 2 8 - >1 4 2 5 8从5> 2开始交换
1 4 2 5 8 - >1 4 2 5 8现在由于这些元素已经按顺序排列8> 5算法不会交换它们。
#### 第二次通过:
1 4 2 5 8 - >1 4 2 5 8
1 4 2 5 8 - >1 2 4 5 8从4> 2开始交换
1 2 4 5 8 - >1 2 4 5 8
1 2 4 5 8 - >1 2 4 5 8
现在,数组已经排序,但我们的算法不知道它是否已完成。该算法需要一个完整的传递,没有任何交换,知道它已经排序。
#### 第三次通过:
1 2 4 5 8 - >1 2 4 5 8
1 2 4 5 8 - >1 2 4 5 8
1 2 4 5 8 - >1 2 4 5 8
1 2 4 5 8 - >1 2 4 5 8
#### 属性
* 空间复杂度O1
* 最佳案例表现On
* 平均案例表现On \* n
* 最差案例表现On \* n
* 稳定:是的
### 视频说明
[冒泡以简单的方式排序](https://www.youtube.com/watch?v=Jdtq5uKz-w4)
此代码将使用冒泡排序对数组进行排序。
```js
let arr = [1, 4, 7, 45, 7,43, 44, 25, 6, 4, 6, 9];
let sorted = false
while(!sorted) {
sorted = true
for(var i=0; i < arr.length; i++) {
if(arr[i] < arr[i-1]) {
let temp = arr[i];
arr[i] = arr[i-1];
arr[i-1] = temp;
sorted = false;
}
}
}
```
### 属性:
* 空间复杂度O1
* 时间复杂度分别为最佳平均和最差情况的OnOn \* nOn \* n
* 到位:是的
* 稳定:是的
\======= 这是用Java编写的算法。
```java
public class bubble-sort {
static void sort(int[] arr) {
int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++){
for(int x=1; x < (ni); x++){
if(arr[x-1] > arr[x]){
temp = arr[x-1];
arr[x-1] = arr[x];
arr[x] = temp;
}
}
}
}
public static void main(String[] args) {
for(int i=0; i < 15; i++){
int arr[i] = (int)(Math.random() * 100 + 1);
}
System.out.println("array before sorting\n");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
bubbleSort(arr);
System.out.println("\n array after sorting\n");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
```
\=======
### 冒泡排序的递归实现。
```c++
void bubblesort(int arr[], int n)
{
if(n==1) //Initial Case
return;
for(int i=0;i<n-1;i++) //After this pass the largest element will move to its desired location.
{
if(arr[i]>arr[i+1])
{
temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
bubblesort(arr,n-1); //Recursion for remaining array
}
```
### 更多信息
* [维基百科](https://en.wikipedia.org/wiki/Bubble_sort)
* [冒泡排序算法 - CS50](https://youtu.be/Ui97-_n5xjo)
* [冒泡排序算法 - GeeksForGeeks文章](http://www.geeksforgeeks.org/bubble-sort)
* [冒泡排序算法 - MyCodeSchool视频](https://www.youtube.com/watch?v=Jdtq5uKz-w4)
* [算法:冒泡排序 - HackerRank视频](https://www.youtube.com/watch?v=6Gv8vg0kcHc)
* [冒泡排序算法 - GeeksForGeeks视频](https://www.youtube.com/watch?v=nmhjrI-aW5o)
* [冒泡排序可视化](https://www.hackerearth.com/practice/algorithms/sorting/bubble-sort/visualize/)

View File

@@ -0,0 +1,46 @@
---
title: Bucket Sort
localeTitle: 铲斗排序
---
## 什么是Bucket Sort
Bucket sort是一种比较排序算法它通过将元素划分为不同的存储区然后对这些存储区进行排序来对元素进行操作 个别。每个存储桶使用单独的排序算法或递归应用存储桶排序算法单独排序。 当输入均匀分布在一个范围内时,存储桶排序主要是有用的。
## 假设一个人面前有以下问题:
已经给出了一个大的浮点整数阵列,它们均匀地位于下界和上界之间。现在需要这个阵列 排序。解决此问题的一种简单方法是使用其他排序算法,例如合并排序,堆排序或快速排序。然而, 这些算法保证了ONlogN的最佳案例时间复杂度。 但是使用桶排序上述任务可以在ON时间内完成。
让我们仔细看看吧。
考虑一个需要创建一个列表数组,即桶。现在需要根据元素的属性将元素插入到这些桶中。 然后可以使用“插入排序”单独对每个存储桶进行排序。
### 铲斗的伪代码排序:
```
void bucketSort(float[] a,int n)
{
for(each floating integer 'x' in n)
{
insert x into bucket[n*x];
}
for(each bucket)
{
sort(bucket);
}
}
```
### 更多信息:
* [维基百科](https://en.wikipedia.org/wiki/Bucket_sort)
* [GeeksForGeeks](http://www.geeksforgeeks.org/bucket-sort-2/)

View File

@@ -0,0 +1,56 @@
---
title: Counting Sort
localeTitle: 计数排序
---
## 计数排序
Counting Sort是一种基于特定范围之间的键的排序技术。它的工作原理是计算具有不同键值的对象数散列类型。然后做一些算术来计算输出序列中每个对象的位置。
### 例:
```
For simplicity, consider the data in the range 0 to 9.
Input data: 1, 4, 1, 2, 7, 5, 2
1) Take a count array to store the count of each unique object.
Index: 0 1 2 3 4 5 6 7 8 9
Count: 0 2 2 0 1 1 0 1 0 0
2) Modify the count array such that each element at each index
stores the sum of previous counts.
Index: 0 1 2 3 4 5 6 7 8 9
Count: 0 2 4 4 5 6 6 7 7 7
The modified count array indicates the position of each object in
the output sequence.
3) Output each object from the input sequence followed by
decreasing its count by 1.
Process the input data: 1, 4, 1, 2, 7, 5, 2. Position of 1 is 2.
Put data 1 at index 2 in output. Decrease count by 1 to place
next data 1 at an index 1 smaller than this index.
```
### 履行
```js
let numbers = [1, 4, 1, 2, 7, 5, 2];
let count = [];
let i, z = 0;
let max = Math.max(...numbers);
// initialize counter
for (i = 0; i <= max; i++) {
count[i] = 0;
}
for (i=0; i < numbers.length; i++) {
count[numbers[i]]++;
}
for (i = 0; i <= max; i++) {
while (count[i]-- > 0) {
numbers[z++] = i;
}
}
// output sorted array
for (i=0; i < numbers.length; i++) {
console.log(numbers[i]);
}
```

View File

@@ -0,0 +1,133 @@
---
title: Heapsort
localeTitle: 堆排序
---
## 堆排序
Heapsort是一种基于最大/最小堆使用的高效排序算法。堆是基于树的数据结构,它满足堆属性 - 即对于最大堆任何节点的密钥小于或等于其父节点的密钥如果它具有父节点。可以使用此属性来使用maxHeapify方法在Ologn时间内访问堆中的最大元素。我们执行此操作n次每次将堆中的最大元素移动到堆的顶部并将其从堆中提取到一个已排序的数组中。因此在n次迭代之后我们将得到输入数组的排序版本。该算法在Onlogn时间和O1附加空间\[On中运行包括存储输入数据所需的空间\],因为所有操作都是完全就地执行的。
Heapsort的最差和平均案例时间要素是Onlogn。尽管heapsort比quicksort具有更好的恶劣情况复杂性但实施良好的快速排序运行速度更快。这是一种基于比较的算法因此它可以用于非数值数据集因为可以在元素上定义某些关系堆属性
Java中的实现如下所示
```java
import java.util.Arrays;
public class Heapsort {
public static void main(String[] args) {
//test array
Integer[] arr = {1, 4, 3, 2, 64, 3, 2, 4, 5, 5, 2, 12, 14, 5, 3, 0, -1};
String[] strarr = {"hope you find this helpful!", "wef", "rg", "q2rq2r", "avs", "erhijer0g", "ewofij", "gwe", "q", "random"};
arr = heapsort(arr);
strarr = heapsort(strarr);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(strarr));
}
//O(nlogn) TIME, O(1) SPACE, NOT STABLE
public static <E extends Comparable<E>> E[] heapsort(E[] arr){
int heaplength = arr.length;
for(int i = arr.length/2; i>0;i--){
arr = maxheapify(arr, i, heaplength);
}
for(int i=arr.length-1;i>=0;i--){
E max = arr[0];
arr[0] = arr[i];
arr[i] = max;
heaplength--;
arr = maxheapify(arr, 1, heaplength);
}
return arr;
}
//Creates maxheap from array
public static <E extends Comparable<E>> E[] maxheapify(E[] arr, Integer node, Integer heaplength){
Integer left = node*2;
Integer right = node*2+1;
Integer largest = node;
if(left.compareTo(heaplength) <=0 && arr[left-1].compareTo(arr[node-1]) >= 0){
largest = left;
}
if(right.compareTo(heaplength) <= 0 && arr[right-1].compareTo(arr[largest-1]) >= 0){
largest = right;
}
if(largest != node){
E temp = arr[node-1];
arr[node-1] = arr[largest-1];
arr[largest-1] = temp;
maxheapify(arr, largest, heaplength);
}
return arr;
}
}
```
在C ++中实现
```C++
#include <iostream>
using namespace std;
void heapify(int arr[], int n, int i)
{
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;
if (l < n && arr[l] > arr[largest])
largest = l;
if (r < n && arr[r] > arr[largest])
largest = r;
if (largest != i)
{
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
void heapSort(int arr[], int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
for (int i=n-1; i>=0; i--)
{
swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
void printArray(int arr[], int n)
{
for (int i=0; i<n; ++i)
cout << arr[i] << " ";
cout << "\n";
}
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
cout << "Sorted array is \n";
printArray(arr, n);
}
```
### 可视化
* [USFCA](https://www.cs.usfca.edu/~galles/visualization/HeapSort.html)
* [HackerEarth](https://www.hackerearth.com/practice/algorithms/sorting/heap-sort/tutorial/)
#### 更多信息:
* [维基百科](https://en.wikipedia.org/wiki/Quicksort)

View File

@@ -0,0 +1,54 @@
---
title: Sorting Algorithms
localeTitle: 排序算法
---
## 排序算法
排序算法是一组指令,它将数组或列表作为输入并将项排列为特定顺序。
排序最常见的是数字或字母称为词典顺序的形式并且可以按升序AZ0-9或降序ZA9-0顺序排列。
### 为什么排序算法很重要
由于排序通常可以降低问题的复杂性,因此它是计算机科学中的一种重要算法。这些算法直接应用于搜索算法,数据库算法,分而治之的方法,数据结构算法等等。
### 一些常见的排序算法
一些最常见的排序算法是:
* 选择排序
* 冒泡排序
* 插入排序
* 合并排序
* 快速排序
* 堆排序
* 计数排序
* 基数排序
* 铲斗排序
### 排序算法的分类
可以基于以下参数对排序算法进行分类:
1. 基于互换次数或反转次数 这是算法交换元素以对输入进行排序的次数。 `Selection Sort`需要最小数量的交换。
2. 基于比较数 这是算法比较元素以对输入进行排序的次数。使用[Big-O表示法](https://guide.freecodecamp.org/computer-science/notation/big-o-notation/) ,上面列出的排序算法示例在最佳情况下需要至少`O(nlogn)`比较,并且在最坏情况下对于大多数输出​​需要`O(n^2)`比较。
3. 基于递归或非递归 某些排序算法(如`Quick Sort` )使用递归技术对输入进行排序。其他排序算法,例如`Selection Sort``Insertion Sort` ,使用非递归技术。最后,一些排序算法,如`Merge Sort` ,使用递归和非递归技术对输入进行排序。
4. 基于稳定性 如果算法保持具有相等键的元素的相对顺序,则称排序算法是`stable`的。换句话说,两个等效元素在排序输出中保持与输入中相同的顺序。
* `Insertion sort` `Merge Sort``Bubble Sort`是稳定的
* `Heap Sort``Quick Sort`不稳定
1. 基于额外空间要求 如果排序算法需要恒定的`O(1)`额外空间进行排序,则称它们`in place`
* `Insertion sort``Quick-sort` `in place`因为我们移动关于数据透视的元素并且实际上不使用单独的数组,这在合并排序中不是这种情况,其中必须事先分配输入的大小以在输出期间存储输出。分类。
* `Merge Sort`是一个`out place` sort的例子因为它需要额外的内存空间来进行操作。
### 任何基于比较的排序的最佳时间复杂度
任何基于比较的排序算法必须至少进行nLog2n比较以对输入数组进行排序而Heapsort和merge排序是渐近最优的比较排序。这可以通过绘制desicion树图来轻松证明。

View File

@@ -0,0 +1,191 @@
---
title: Insertion Sort
localeTitle: 插入排序
---
## 插入排序
插入排序是针对少量元素的最简单有效的排序算法。
### 例:
在插入排序中,将`key`元素与先前元素进行比较。如果前面的元素大于`key`元素,则将前一个元素移动到下一个位置。
从索引1开始到输入数组的大小。
\[8 3 5 1 4 2\]
步骤1
[\[8 3 5 1 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/1.png?raw=true)
```
key = 3 //starting from 1st index.
Here `key` will be compared with the previous elements.
In this case, `key` is compared with 8. since 8 > 3, move the element 8
to the next position and insert `key` to the previous position.
Result: [ 3 8 5 1 4 2 ]
```
第2步
[\[3 8 5 1 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/2.png?raw=true)
```
key = 5 //2nd index
8 > 5 //move 8 to 2nd index and insert 5 to the 1st index.
Result: [ 3 5 8 1 4 2 ]
```
第3步
[\[3 5 8 1 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/3.png?raw=true)
```
key = 1 //3rd index
8 > 1 => [ 3 5 1 8 4 2 ]
5 > 1 => [ 3 1 5 8 4 2 ]
3 > 1 => [ 1 3 5 8 4 2 ]
Result: [ 1 3 5 8 4 2 ]
```
第4步
[\[1 3 5 8 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/4.png?raw=true)
```
key = 4 //4th index
8 > 4 => [ 1 3 5 4 8 2 ]
5 > 4 => [ 1 3 4 5 8 2 ]
3 > 4 ≠> stop
Result: [ 1 3 4 5 8 2 ]
```
第5步
[\[1 3 4 5 8 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/5.png?raw=true)
```
key = 2 //5th index
8 > 2 => [ 1 3 4 5 2 8 ]
5 > 2 => [ 1 3 4 2 5 8 ]
4 > 2 => [ 1 3 2 4 5 8 ]
3 > 2 => [ 1 2 3 4 5 8 ]
1 > 2 ≠> stop
Result: [1 2 3 4 5 8]
```
[\[1 2 3 4 5 8\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/6.png?raw=true)
以下算法是略微优化的版本,以避免在每次迭代中交换`key`元素。这里, `key`元素将在迭代结束时交换(步骤)。
```Algorithm
InsertionSort(arr[])
for j = 1 to arr.length
key = arr[j]
i = j - 1
while i > 0 and arr[i] > key
arr[i+1] = arr[i]
i = i - 1
arr[i+1] = key
```
以下是Javascript中的详细实现
```
function insertion_sort(A) {
var len = array_length(A);
var i = 1;
while (i < len) {
var x = A[i];
var j = i - 1;
while (j >= 0 && A[j] > x) {
A[j + 1] = A[j];
j = j - 1;
}
A[j+1] = x;
i = i + 1;
}
}
```
Swift中的快速实现如下所示
```swift
var array = [8, 3, 5, 1, 4, 2]
func insertionSort(array:inout Array<Int>) -> Array<Int>{
for j in 0..<array.count {
let key = array[j]
var i = j-1
while (i > 0 && array[i] > key){
array[i+1] = array[i]
i = i-1
}
array[i+1] = key
}
return array
}
```
Java示例如下所示
```
public int[] insertionSort(int[] arr)
for (j = 1; j < arr.length; j++) {
int key = arr[j]
int i = j - 1
while (i > 0 and arr[i] > key) {
arr[i+1] = arr[i]
i -= 1
}
arr[i+1] = key
}
return arr;
```
### 在...中插入排序。
```C
void insertionSort(int arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i-1;
while (j >= 0 && arr[j] > key)
{
arr[j+1] = arr[j];
j = j-1;
}
arr[j+1] = key;
}
}
```
### 属性:
* 空间复杂度O1
* 时间复杂度OnOn \* nOn \* n分别为最佳平均最差情况
* 排序到位:是的
* 稳定:是的
#### 其他资源:
* [维基百科](https://en.wikipedia.org/wiki/Insertion_sort)
* [CS50 - YouTube](https://youtu.be/TwGb6ohsvUU)
* [SortInsertion - GeeksforGeeksYouTube](https://www.youtube.com/watch?v=wObxd4Kx8sE)
* [插入排序可视化](https://www.hackerearth.com/practice/algorithms/sorting/insertion-sort/visualize/)

View File

@@ -0,0 +1,204 @@
---
title: Merge Sort
localeTitle: 合并排序
---
## 合并排序
Merge Sort是一种[Divide and Conquer](https://guide.freecodecamp.org/algorithms/divide-and-conquer-algorithms)算法。它将输入数组分为两半,为两半调用自身,然后合并两个已排序的一半。算法的主要部分给出了两个排序的数组,我们必须将它们合并为一个排序的数组。有一种称为[双指算法的](http://www.geeksforgeeks.org/merge-two-sorted-arrays/)东西可以帮助我们将两个已排序的数组合并在一起。使用这个子例程并递归调用数组半部分上的合并排序函数将为我们提供我们正在寻找的最终排序数组。
由于这是一个基于递归的算法,我们有一个递归关系。递归关系只是一种根据子问题表示问题的方法。
`T(n) = 2 * T(n / 2) + O(n)`
用简单的英语说,我们在每一步都将子问题分解为两部分,我们需要做一些线性的工作,以便在每一步将两个分类的一半合并在一起。
```
T(n) = 2T(n/2) + n
= 2(2T(n/4) + n/2) + n
= 4T(n/4) + n + n
= 4(2T(n/8) + n/4) + n + n
= 8T(n/8) + n + n + n
= nT(n/n) + n + ... + n + n + n
= n + n + ... + n + n + n
```
计算结尾总和中n的重复次数我们看到它们有lg n + 1。因此运行时间是nlg n + 1= n lg n + n。我们观察到对于n> 0n lg n + n <n lg n + n lg n = 2n lg n因此运行时间为On lg n)。
```Algorithm
MergeSort(arr[], left, right):
If right > l:
1. Find the middle point to divide the array into two halves:
mid = (left+right)/2
2. Call mergeSort for first half:
Call mergeSort(arr, left, mid)
3. Call mergeSort for second half:
Call mergeSort(arr, mid+1, right)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, left, mid, right)
```
![Merge Sort Algorithm](https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Merge_sort_algorithm_diagram.svg/300px-Merge_sort_algorithm_diagram.svg.png)
### Properties:
* Space Complexity: O(n)
* Time Complexity: O(n*log(n)). The time complexity for the Merge Sort might not be obvious from the first glance. The log(n) factor that comes in is because of the recurrence relation we have mentioned before.
* Sorting In Place: No in a typical implementation
* Stable: Yes
* Parallelizable :yes (Several parallel variants are discussed in the third edition of Cormen, Leiserson, Rivest, and Stein's Introduction to Algorithms.)
### Visualization:
* <a href='https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html'>USFCA</a>
* <a href='https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/visualize/'>HackerEarth</a>
### Relavant videos on freeCodeCamp YouTube channel
* <a href='https://youtu.be/TzeBrDU-JaY'>Merge Sort algorithm - MyCodeSchool</a>
### Other Resources:
* <a href='https://en.wikipedia.org/wiki/Merge_sort' target='_blank' rel='nofollow'>Wikipedia</a>
* <a href='www.geeksforgeeks.org/merge-sort' target='_blank' rel='nofollow'>GeeksForGeeks</a>
* <a href='https://youtu.be/sWtYJv_YXbo' target='_blank' rel='nofollow'>Merge Sort - CS50</a>
### Implementaion in JS
```
JS const list = \[23,4,42,15,16,8,3\]
const mergeSort =list=> { iflist.length <= 1返回列表; const middle = list.length / 2; const left = list.slice0middle; const right = list.slicemiddlelist.length; return mergemergeSortmergeSort; }
const merge =leftright=> { var result = \[\]; whileleft.length || right.length{ ifleft.length && right.length{ ifleft \[0\] <right \[0\]{ result.pushleft.shift } else { result.pushright.shift } } else ifleft.length{ result.pushleft.shift } else { result.pushright.shift } } 返回结果; }
console.logmergeSortlist// \[3,4,8,15,16,23,42\]
```
### Implementation in C
```
C
# 包括
# 包括
void mergeint arr \[\]int lint mint r { int ijk; int n1 = m - l + 1; int n2 = r - m;
```
int L[n1], R[n2];
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
```
}
void mergeSortint arr \[\]int lint r { ifl <r {
int m = l +rl/ 2;
```
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
```
} void printArrayint A \[\]int size { int i; fori = 0; i <size; i ++ printf(“%d”,A \[i\]; 的printf \\ n”); } int main { int arr \[\] = {12,11,13,5,6,7}; int arr\_size = sizeofarr/ sizeofarr \[0\];
```
printf("Given array is \n");
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
printf("\nSorted array is \n");
printArray(arr, arr_size);
return 0;
```
```
### Implementation in C++
Let us consider array A = {2,5,7,8,9,12,13}
and array B = {3,5,6,9,15} and we want array C to be in ascending order as well.
```
C ++ void mergesortint A \[\]int size _aint B \[\]int size_ bint C \[\] { int token _atoken_ btoken _c; for令牌_ a = 0令牌_b = 0令牌_ c = 0;令牌_a_ _a &&标记_b__ __b; { ifA \[token _a\] <= B \[token_ b\] C \[token _c ++\] = A \[token_ a ++\]; 其他 C \[token _c ++\] = B \[token_ b ++\]; }__
```
if(token_a<size_a)
{
while(token_a<size_a)
C[token_c++]=A[token_a++];
}
else
{
while(token_b<size_b)
C[token_c++]=B[token_b++];
}
```
}
```
### Implementation in Python
```
蟒蛇 temp = def合并arrleftright 全球温度反转 mid =(左+右)// 2 对于范围内的i+ 1 temp \[i\] = arr \[i\]
```
k, L, R = left, left, mid + 1
while L <= mid and R <= right:
if temp[L] <= temp[R]:
arr[k] = temp[L]
L += 1
else:
arr[k] = temp[R]
R += 1
k += 1
while L <= mid:
arr[k] = temp[L]
L += 1
k += 1
while R <= right:
arr[k] = temp[R]
R += 1
k += 1
```
def merge\_sortarrleftright 如果左> =右: 返回
```
mid = (left + right) // 2
merge_sort(arr, left, mid)
merge_sort(arr, mid + 1, right)
merge(arr, left, right)
```
arr = \[1,6,3,1,8,4,2,9,3\] temp = \[范围内没有\_lenarr\] merge\_sortarr0lenarr - 1 打印arrinversions \`\`\`

View File

@@ -0,0 +1,146 @@
---
title: Quick Sort
localeTitle: 快速排序
---
## 快速排序
快速排序是一种有效的分而治之的排序算法。 Quick Sort的平均案例时间复杂度为Onlogn最坏情况时间复杂度为On ^ 2
快速排序涉及的步骤是:
* 选择一个元素作为数据透视表,在这种情况下,数组的最后一个元素是数据透视表。
* 分区:对阵列进行排序,使得小于枢轴的所有元素都在左侧,并且所有大于枢轴的元素都在右侧。
* 以递归方式调用Quicksort考虑前一个枢轴以正确细分左右数组。 (更详细的解释可以在下面的评论中找到)
JavaScript中的快速实现
```javascript
const arr = [6, 2, 5, 3, 8, 7, 1, 4]
const quickSort = (arr, start, end) => {
if(start < end) {
// You can learn about how the pivot value is derived in the comments below
let pivot = partition(arr, start, end)
// Make sure to read the below comments to understand why pivot - 1 and pivot + 1 are used
// These are the recursive calls to quickSort
quickSort(arr, start, pivot - 1)
quickSort(arr, pivot + 1, end)
}
}
const partition = (arr, start, end) => {
let pivot = end
// Set i to start - 1 so that it can access the first index in the event that the value at arr[0] is greater than arr[pivot]
// Succeeding comments will expound upon the above comment
let i = start - 1
let j = start
// Increment j up to the index preceding the pivot
while (j < pivot) {
// If the value is greater than the pivot increment j
if (arr[j] > arr[pivot]) {
j++
}
// When the value at arr[j] is less than the pivot:
// increment i (arr[i] will be a value greater than arr[pivot]) and swap the value at arr[i] and arr[j]
else {
i++
swap(arr, j, i)
j++
}
}
//The value at arr[i + 1] will be greater than the value of arr[pivot]
swap(arr, i + 1, pivot)
//You return i + 1, as the values to the left of it are less than arr[i+1], and values to the right are greater than arr[i + 1]
// As such, when the recursive quicksorts are called, the new sub arrays will not include this the previously used pivot value
return i + 1
}
const swap = (arr, firstIndex, secondIndex) => {
let temp = arr[firstIndex]
arr[firstIndex] = arr[secondIndex]
arr[secondIndex] = temp
}
quickSort(arr, 0, arr.length - 1)
console.log(arr)
```
C中的快速排序实现
```C
#include<stdio.h>
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
int partition (int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high- 1; j++)
{
if (arr[j] <= pivot)
{
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("n");
}
int main()
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr, 0, n-1);
printf("Sorted array: n");
printArray(arr, n);
return 0;
}
```
快速排序的空间复杂度是On。这是对其他分治和征服排序算法的改进它采用Onlongn空间。快速排序通过更改给定数组中元素的顺序来实现此目的。将其与[合并排序](https://guide.freecodecamp.org/algorithms/sorting-algorithms/merge-sort)算法进行比较该算法在每个函数调用中创建2个数组每个数组长度为n / 2。
#### 更多信息:
* [维基百科](https://en.wikipedia.org/wiki/Quicksort)
* [GeeksForGeeks](http://www.geeksforgeeks.org/quick-sort)
* [YoutubeQuicksort的视觉解释](https://www.youtube.com/watch?v=MZaf_9IZCrc)
* [YoutubeGayle Laakmann McDowellCracking The Coding Interview的作者解释了quicksort的基础知识并展示了一些实现](https://www.youtube.com/watch?v=SLauY6PpjW4)

View File

@@ -0,0 +1,111 @@
---
title: Radix Sort
localeTitle: 基数排序
---
## 基数排序
先决条件:计数排序
QuickSortMergeSortHeapSort是基于比较的排序算法。 CountSort不是基于比较的算法。它具有On + k的复杂度其中k是输入数组的最大元素。 因此如果k是On则CountSort变为线性排序这比具有Onlogn时间复杂度的基于比较的排序算法更好。 当k变为On2想法是扩展CountSort算法以获得更好的时间复杂度。 这是Radix Sort的想法。
算法:
对于每个数字i其中i从最低有效数字到数字的最高有效数字变化 使用countort算法根据第i位数对输入数组进行排序。 我们使用count sort因为它是一个稳定的排序。
示例:假设输入数组是:
10,21,17,34,44,11,654,123
基于该算法,我们将根据一个数字(最低有效数字)对输入数组进行排序。
0:10
1:21 11
2
3123
434 44 654
5
6
7:17
8
9
因此阵列变为10,21,11,123,24,44,654,17 现在,我们将根据十位数进行排序:
0
1:10 11 17
221 123
3:34
4:44
5654
6
7
8
9
现在阵列变为10,11,17,21,123,34,44,654 最后,我们按照百位数(最高位数)进行排序:
0010 011 017 021 034 044
1123
2
3
4
5
6654
7
8
9
该数组变为10,11,17,21,34,44,123,654它被排序。这就是我们的算法的工作方式。
C中的实现
```
void countsort(int arr[],int n,int place){
int i,freq[range]={0}; //range for integers is 10 as digits range from 0-9
int output[n];
for(i=0;i<n;i++)
freq[(arr[i]/place)%range]++;
for(i=1;i<range;i++)
freq[i]+=freq[i-1];
for(i=n-1;i>=0;i--){
output[freq[(arr[i]/place)%range]-1]=arr[i];
freq[(arr[i]/place)%range]--;
}
for(i=0;i<n;i++)
arr[i]=output[i];
}
void radixsort(ll arr[],int n,int maxx){ //maxx is the maximum element in the array
int mul=1;
while(maxx){
countsort(arr,n,mul);
mul*=10;
maxx/=10;
}
}
```
### 更多信息:
* [维基百科](https://en.wikipedia.org/wiki/Radix_sort)
* [GeeksForGeeks](http://www.geeksforgeeks.org/radix-sort/)

View File

@@ -0,0 +1,67 @@
---
title: Selection Sort
localeTitle: 选择排序
---
## 选择排序
Selection Sort是最简单的排序算法之一。它按以下方式工作
1. 找到最小的元素。用第一个元素交换它。
2. 找到第二个最小的元素。用第二个元素交换它。
3. 找到第三个最小的元素。用第三个元素交换它。
4. 重复查找下一个最小元素并将其交换到相应的正确位置,直到对数组进行排序。
正如您所猜测的,此算法称为选择排序,因为它重复选择下一个最小元素并将其交换到其位置。
但是,您如何编写代码来查找数组中第二个最小值的索引?
* 一种简单的方法是注意到最小值已经被交换到索引0中因此问题减少到从索引1开始查找数组中的最小元素。
### 在C / C ++中实现
```C
for(int i = 0; i < n; i++)
{
int min_index = i;
int min_element = a[i];
for(int j = i +1; j < n; j++)
{
if(a[j] < min_element)
{
min_element = a[j];
min_index = j;
}
}
swap(&a[i], &a[min_index]);
}
```
### 在Javascript中实现
\`\`\`Javascript 功能选择_排序A{ var len =数组_长度A; forvar i = 0; i <len - 1; i = i + 1{ var j _min = i; forvar j = i + 1; j <len; j = j + 1{ ifA \[j\] <A \[j_ min\]{ j _min = j; } else {} } ifj_ min== i{ 交换Aij\_min; } else {} } }
函数交换Axy{ var temp = A \[x\]; A \[x\] = A \[y\]; A \[y\] = temp; }
```
### Implementation in Python
```
蟒蛇 def seletion _sortarr 如果不是arr 回归 对于范围内的我lenarr min_ i = i 对于范围内的ji + 1lenarr 如果arr \[j\] <arr \[min _i\] min_ i = j arr \[i\]arr \[min _i\] = arr \[min_ i\]arr \[i\] \`\`\`
### 属性
* 空间复杂度 **On**
* 时间复杂度 **On 2 **
* 按位排序 **是的**
* 稳定 **没有**
### 可视化
* [USFCA](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html)
* [HackerEarth](https://www.hackerearth.com/practice/algorithms/sorting/selection-sort/visualize/)
### 参考
* [维基百科](https://en.wikipedia.org/wiki/Selection_sort)
* [可汗学院](https://www.khanacademy.org/computing/computer-science/algorithms#sorting-algorithms)

View File

@@ -0,0 +1,112 @@
---
title: Timsort
localeTitle: Timsort
---
## Timsort
Timsort是一种快速排序算法在稳定的ON logN复杂度下工作
Timsort融合了Insertion Sort和Mergesort。该算法在Java的Arrays.sort以及Python的sorted和sort中实现。 较小的部分使用Insertion Sort进行排序稍后使用Mergesort合并在一起。
Python中的快速实现
```
def binary_search(the_array, item, start, end):
if start == end:
if the_array[start] > item:
return start
else:
return start + 1
if start > end:
return start
mid = round((start + end)/ 2)
if the_array[mid] < item:
return binary_search(the_array, item, mid + 1, end)
elif the_array[mid] > item:
return binary_search(the_array, item, start, mid - 1)
else:
return mid
"""
Insertion sort that timsort uses if the array size is small or if
the size of the "run" is small
"""
def insertion_sort(the_array):
l = len(the_array)
for index in range(1, l):
value = the_array[index]
pos = binary_search(the_array, value, 0, index - 1)
the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:]
return the_array
def merge(left, right):
"""Takes two sorted lists and returns a single sorted list by comparing the
elements one at a time.
[1, 2, 3, 4, 5, 6]
"""
if not left:
return right
if not right:
return left
if left[0] < right[0]:
return [left[0]] + merge(left[1:], right)
return [right[0]] + merge(left, right[1:])
def timsort(the_array):
runs, sorted_runs = [], []
length = len(the_array)
new_run = [the_array[0]]
# for every i in the range of 1 to length of array
for i in range(1, length):
# if i is at the end of the list
if i == length - 1:
new_run.append(the_array[i])
runs.append(new_run)
break
# if the i'th element of the array is less than the one before it
if the_array[i] < the_array[i-1]:
# if new_run is set to None (NULL)
if not new_run:
runs.append([the_array[i]])
new_run.append(the_array[i])
else:
runs.append(new_run)
new_run = []
# else if its equal to or more than
else:
new_run.append(the_array[i])
# for every item in runs, append it using insertion sort
for item in runs:
sorted_runs.append(insertion_sort(item))
# for every run in sorted_runs, merge them
sorted_array = []
for run in sorted_runs:
sorted_array = merge(sorted_array, run)
print(sorted_array)
timsort([2, 3, 1, 5, 6, 7])
```
#### 复杂:
Tim sort具有稳定的O复杂度N logN与Quicksort相比非常好。 在这张[图表](https://cdn-images-1.medium.com/max/1600/1*1CkG3c4mZGswDShAV9eHbQ.png)上可以找到一个复杂的混合体
#### 更多信息:
* [维基百科](https://en.wikipedia.org/wiki/Timsort)
* [GeeksForGeeks](https://www.geeksforgeeks.org/timsort/)
* [YoutubeQuicksort的视觉解释](https://www.youtube.com/watch?v=jVXsjswWo44)
#### 积分:
[Python实现](https://hackernoon.com/timsort-the-fastest-sorting-algorithm-youve-never-heard-of-36b28417f399)