Algorithm Series 15-day crash the third day of the seven classic sort "down" _ Related tips

Source: Internet
Author: User

Direct Insert Sort:

This sort of sorting is very good to understand, the real example is that we fight the landlord, when we caught a mess of cards, we have to according to size comb poker, 30 seconds later,

Poker comb finished, 4 3, 5 s, wow ... Remember how we combed it at the time.

The left one card is 3, the second card is 5, the third card is 3, hurriedly inserted into the back of the first card, the fourth card is 3, exultation, hurriedly inserted behind the second one,

The fifth card is 3, ecstasy, Haha, a cannon is produced.

How, the life everywhere is the algorithm, has already melted into our life and the blood.

The following illustration shows:

Look at this picture. I don't know if you can understand, in the insert sort, the array is divided into two types, ordered array blocks and unordered array blocks,

Yes, the first time. Extracts a number of 20 as an ordered array block from the unordered array block.

The second time from the "unordered array block" to extract a number 60 ordered into the "ordered array of blocks", that is, 20,60.

The third time. Similarly, the difference is that 10 is smaller than the ordered array, so the 20,60 position is shifted back, freeing up a position for 10 to insert.

Then you can insert all of them in this pattern.

Copy Code code 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:" + string.) Join (",", list));

Insertsort (list);

Console.WriteLine ("After Sort:" + string.) Join (",", list));
}

static void Insertsort (List<int> List)
{
No sequence
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 find out that she has a flaw:

If the data is "5, 4, 3, 2, 1," When we insert the record in the "unordered block" into the "ordered block," We're going to crash,

The insertion order is an efficient place to move each time the insertion is moved.

Shell based on this weakness of the algorithm to improve, into a kind of called "narrowing the Incremental sorting method," the idea is actually quite simple, but a little attention is:

The increment is not random, but has the law to follow.

The first step is to clarify the incremental:

The first increment is: D=COUNT/2;

The second increment is: d= (COUNT/2)/2;

Last until: d=1;

The phenomena observed in the graph are:

When d=3: will 40 and 50 ratio, because 50 big, do not exchange.

Will 20 and 30 ratio, because 30 big, do not exchange.

Compare 80 with 60, because 60 small, exchange.

When d=2: will 40 and 60 ratio, do not exchange, take 60 and 30 than exchange, at this time after the exchange of 30 than the front 40 small, but also 40 and 30 exchange, as shown above.

Compare 20 with 50, do not exchange, continue to 50 compared with 80, do not exchange.

D=1: This is the previous insertion sort, but this time the sequence is almost orderly, so the insertion order has brought a great performance improvement.

Now that "hill sort" is an improved version of "Insert Sort," how much faster can we compare to the 1w number?

Here's a test:

Copy Code code as follows:

Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using System.Threading;
Using System.Diagnostics;

Namespace Shellsort
{
    public class program
    {
         static void Main (string[] args)
        {
           //5 times comparison
             for (int i = 1; I <= 5; i++)
             {
                 list<int> List = new list<int> ();

               //inserting 1w random numbers into an array
                for (int j = 0; J < 10000; J + +)
                {
                     Thread.Sleep (1);
                     list. ADD (new Random (int) DateTime.Now.Ticks). Next (10000, 1000000));
               }

list<int> list2 = new list<int> ();
List2. AddRange (list);

Console.WriteLine ("\ n" + i + "second comparison:");

Stopwatch watch = new stopwatch ();

Watch. Start ();
Insertsort (list);
Watch. Stop ();

Console.WriteLine ("\ n the time spent inserting a sort:" + watch.) Elapsedmilliseconds);
Console.WriteLine ("Output first 10 digits:" + string.) Join (",", list.) Take (10). ToList ()));

Watch. Restart ();
Shellsort (LIST2);
Watch. Stop ();

Console.WriteLine ("Hill Sort time Spent:" + watch.) Elapsedmilliseconds);
Console.WriteLine ("Output first 10 digits:" + string.) Join (",", List2.) Take (10). ToList ()));

}
}

<summary>
Hill sort
</summary>
<param name= "List" ></param>
static void Shellsort (List<int> List)
{
Take increment
int step = list. COUNT/2;

while (step >= 1)
{
No sequence
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>
Insert Sort
</summary>
<param name= "List" ></param>
static void Insertsort (List<int> List)
{
No sequence
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;
}
}
}
}

Screenshot below:

Look out, Hill sort of optimized a lot, W-level of the sort, the difference is 70 times wow.

Merge sort:

Personal feeling, we can easily see the sort of understanding is basically O (n^2), more ugly understand is basically n (logn), so merge sort is also more difficult to understand, especially in the code

Written on, I was engaged in the afternoon just to get out, Xi hee.

First look at the picture:

Two things to do in the merge sort:

The first: "Divide" is to divide the array as far as possible, all the way to the atomic level.

Second: "and", the atomic level of number 22 is sorted, and finally produces results.

Code:

Copy Code code 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 </param> to be sorted;
///<param name= "Temparray" > Temporary storage array </param>
///< Param name= The start position of the "left" > Sequence segment, </param>
///<param name= The end position of the "right" > Sequence segment </param>
         static void MergeSort (int[] array, int[] temparray, int left, int right)
 & nbsp;      {
            if ( Left < right)
            {
                //Take split position
                 int middle = (left + right)/2;

Recursive partitioning of the left sequence of an array
MergeSort (array, Temparray, left, middle);

Recursive partitioning of the right sequence of arrays
MergeSort (array, Temparray, middle + 1, right);

Array merge operations
Merge (array, Temparray, left, Middle + 1, right);
}
}

<summary>
22 merge operations for arrays
</summary>
<param name= "Array" > arrays to be sorted </param>
<param name= "Temparray" > Temporary array </param>
<param name= "Left" > First interval segment start position </param>
<param name= "Middle" > Start position of the second interval </param>
<param name= "Right" > second interval end position </param>
static void Merge (int[] array, int[] temparray, int left, int middle, int right)
{
Left pointer tail
int leftend = middle-1;

Right pointer header
int rightstart = middle;

Subscript for a temporary array
int tempindex = left;

Length of array after merging
int templength = right-left + 1;

First loop, two intervals, no end
while (left <= leftend) && (RightStart <= right))
{
If a sequence is found to be large, put the number in a temporary array
if (Array[left] < Array[rightstart])
temparray[tempindex++] = array[left++];
Else
temparray[tempindex++] = array[rightstart++];
}

To determine whether the left sequence ends
while (left <= leftend)
temparray[tempindex++] = array[left++];

To determine whether the right sequence ends
while (RightStart <= right)
temparray[tempindex++] = array[rightstart++];

Exchanging data
for (int i = 0; i < templength; i++)
{
Array[right] = Temparray[right];
right--;
}
}
}
}

Result diagram:

PS: The time complexity of inserting sort is: O (n^2)

The time complexity of hill sort is as follows: The average is: O (N^3/2)

Worst: O (n^2)

Merge sort time complexity of: O (NLOGN)

The complexity of the space is: O (N)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.