Direct insertion sort:

This sort is actually quite understandable. A real example is that we fight against landlords. When we catch a hand of random cards, we have to sort out the cards according to their size. After 30 seconds,

After carding poker, 4 3, 5 s, wow… recall how we did it at that time.

The leftmost card is 3, the second card is 5, and the third card is 3. Put it behind the first card, and the fourth card is 3. Thank you very much. Put it behind the second card.

The fifth card is 3, ecstasy, haha, a gun was produced.

Well, there are algorithms everywhere in our life, which have already been integrated into our life and blood.

Following is the illustration of the above picture: \\\\\\\\\\\\

Looking at this picture, I don’t know if you can understand it. In insertion sort, arrays are divided into two kinds, “ordered array block” and “disordered array block”.

Yes, in the first pass, a number 20 is extracted from the “disordered array block” as an ordered array block.

On the second pass, an orderly number of 60 is extracted from the “disordered array block” and placed in the “ordered array block”, that is, 20,60.

On the third pass, the same thing happens, except that 10 is found to be smaller than the value of an ordered array, so 20, 60 positions are moved back and a position is set aside for 10 to insert.

Then, according to this rule, all inserts can be completed.

Copy codeThe code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InsertSort
{
public class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>() { 3, 1, 2, 9, 7, 8, 6 };

Console. WriteLine (“Before Sorting:”+string. Join (“,”, list)));

InsertSort(list);

Console.WriteLine (“After Sorting:”+string.Join (“,”, list));
}

static void InsertSort(List<int> list)
{
// No sequence required
for (int i = 1; i < list.Count; i++)
{
var temp = list[i];

int j;

// Ordered sequence
for (j = i – 1; j >= 0 && temp < list[j]; j–)
{
list[j + 1] = list[j];
}
list[j + 1] = temp;
}
}
}
}

Hill Sort:

Look at Insert Sort: It’s not hard to see that she has a weakness:

If the data is “5, 4, 3, 2, 1”, then we insert the records in the “disordered block” into the “ordered block”, we estimate that we will crash.

Each insert moves its position, and the efficiency of insertion sort can be imagined.

According to this weakness, shell has improved its algorithm and incorporated an idea called “Reduced Incremental Sorting”, which is actually quite simple, but a little attention is paid to:

Increments are not arbitrary, but regular.

First of all, we need to clarify the method of increment.

The first increment is d = count/2.

The second increment is d=(count/2)/2.

Last until: d = 1;

The phenomena observed in the picture above are as follows:

D = 3:40 to 50, because 50 is big, no exchange.

Compare 20 to 30, because 30 is big, no exchange.

Compare 80 to 60, because 60 is small, exchange.

D = 2:40 to 60, no exchange, 60 to 30, then 30 is smaller than 40, and 40 and 30 are exchanged, as shown above.

Will 20 to 50, no exchange, continue to 50 to 80, no exchange.

D = 1: This is the insertion sort mentioned earlier, but the sequence is almost ordered at this time, so it brings great performance improvement to the insertion sort.

Since Hill Sorting is an improved version of Insert Sorting, how much faster can we get in a wh number than that?

Here’s a test:

Copy codeThe code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ShellSort
{
public class Program
{
static void Main(string[] args)
{
// Five comparisons
for (int i = 1; i <= 5; i++)
{
List<int> list = new List<int>();

// Insert 1W random numbers into the array
for (int j = 0; j < 10000; j++)
{
}

List<int> list2 = new List<int>();

Console. WriteLine (” n th”+i+sub-comparison:”);

Stopwatch watch = new Stopwatch();

watch.Start();
InsertSort(list);
watch.Stop();

Console. WriteLine (” n insert sort time:”+ watch. Elapsed Milliseconds”;
Console. WriteLine (“Top Ten Numbers of Output:” + string. Join (“,”), list. Take (10). ToList ()));

watch.Restart();
ShellSort(list2);
watch.Stop();

Console. WriteLine (” nHill Sorting Time:”+ watch. Elapsed Milliseconds”;
Console. WriteLine (“Top Ten Numbers of Output:” + string. Join (“,”, list2. Take (10). ToList ()));

}
}

///<summary>
/// Hill sort
///</summary>
///<param name=”list”></param>
static void ShellSort(List<int> list)
{
// Incremental
int step = list.Count / 2;

while (step >= 1)
{
// No sequence required
for (int i = step; i < list.Count; i++)
{
var temp = list[i];

int j;

// Ordered sequence
for (j = i – step; j >= 0 && temp < list[j]; j = j – step)
{
list[j + step] = list[j];
}
list[j + step] = temp;
}
step = step / 2;
}
}

///<summary>
/// Insertion sort
///</summary>
///<param name=”list”></param>
static void InsertSort(List<int> list)
{
// No sequence required
for (int i = 1; i < list.Count; i++)
{
var temp = list[i];

int j;

// Ordered sequence
for (j = i – 1; j >= 0 && temp < list[j]; j–)
{
list[j + 1] = list[j];
}
list[j + 1] = temp;
}
}
}
}

The screenshots are as follows:

As you can see, Hill ranking has been optimized a lot. In w ranking, the difference is more than 70 times wow.

Merge Sort:

Personally, the sort that we can easily understand is basically O (n ^ 2), and the sort that is more difficult to understand is basically N (LogN), so merge sort is also more difficult to understand, especially in the code.

Writing, I just did it all afternoon, giggling.

First look at the picture:

There are two things to do in merging and sorting:

The first is “score”, which is to divide arrays as far as possible, up to the atomic level.

The second one is “union”, which combines two atoms and ranks them, and finally produces results.

Code:

Copy codeThe code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MergeSort
{
class Program
{
static void Main(string[] args)
{
int[] array = { 3, 2, 1, 8, 9, 0 };

MergeSort(array, new int[array.Length], 0, array.Length – 1);

Console.WriteLine(string.Join(“,”, array));
}

///<summary>
/// Array partition
///</summary>
/// <param name=”array”>array to be sorted </param>
/// <param name=”temparray”>temporary storage array </param>
/// <param name=”left”>the starting position of sequence segment,</param>
/// <param name=”right”>end position of sequence segment </param>
static void MergeSort(int[] array, int[] temparray, int left, int right)
{
if (left < right)
{
// Segmentation location
int middle = (left + right) / 2;

// Recursively partitioning the left sequence of arrays
MergeSort(array, temparray, left, middle);

// Recursively partitioning the right sequence of arrays
MergeSort(array, temparray, middle + 1, right);

// Number combination and operation
Merge(array, temparray, left, middle + 1, right);
}
}

///<summary>
/// Binary merging of arrays
///</summary>
/// <param name=”array”>array to be sorted </param>
/// <param name=”temparray”>temporary array </param>
/// <param name=”left”>the starting position of the first interval </param>
/// <param name=”middle”>the starting position of the second interval </param>
/// <param name=”right”>end position of the second interval </param>
static void Merge(int[] array, int[] temparray, int left, int middle, int right)
{
// Left pointer tail
int leftEnd = middle – 1;

int rightStart = middle;

// Subscription of Temporary Array
int tempIndex = left;

// Length Length after Combination of Numbers
int tempLength = right – left + 1;

// The case where neither interval of the first cycle ends
while ((left <= leftEnd) && (rightStart <= right))
{
// If an ordered column is found to be large, it is placed in a temporary array
if (array[left] < array[rightStart])
temparray[tempIndex++] = array[left++];
else
temparray[tempIndex++] = array[rightStart++];
}

// Judging whether the left sequence ends
while (left <= leftEnd)
temparray[tempIndex++] = array[left++];

// Judging whether the right sequence ends
while (rightStart <= right)
temparray[tempIndex++] = array[rightStart++];

// Exchange of data
for (int i = 0; i < tempLength; i++)
{
array[right] = temparray[right];
right–;
}
}
}
}

Result figure:

Ps: The time complexity of insertion sort is: O (N ^ 2)

The time complexity of Hill sort is: O (N ^ 3/2) on average.

Worst: O (N ^ 2)

The time complexity of merge sort is: O (NlogN)

The spatial complexity is O(N)