A summary of the stability and time complexity of all sorts of algorithms

Source: Internet
Author: User
Tags sorts
Select Sort, quick sort, hill sort, heap sort is not a stable sort algorithm, bubble sort, insert sort, merge sort and cardinality ordering are stable sorting algorithms.


Bubble method:
This is the most primitive, and also known as the slowest algorithm. The origin of his name was because its work seemed to be bubbling: The complexity was O (n*n). When the data is in positive order, there will be no exchange. The degree of complexity is O (0).

Direct Insertion Sort: O (n*n)

Select sort: O (n*n)

Quick sort: Average time complexity log2 (n) *n, the highest in all internal sorting methods, and is always best in most cases.

Merge sort: log2 (n) *n

Heap Sort: log2 (n) *n

Hill sort: The complexity of the algorithm is N of 1.2 times the power


Here I do not give an analysis of behavior, because this is very simple, we directly to analyze the algorithm:

First, let's consider the ideal situation.
1. The size of an array is a power of 2, which can always be divisible by 2. Suppose to be 2 K-th side, i.e. K=LOG2 (n).
2. Each time we choose a value that is just an intermediate value, the array can be divided equally.
First-level recursion, cyclic n-times, second-layer cyclic 2* (N/2) ...
So altogether n+2 (N/2) +4 (N/4) +...+n* (n/n) = N+N+N+...+N=K*N=LOG2 (n) *n
So the algorithmic complexity is O (log2 (n) *n)
Other situations are only worse than this, and the worst case scenario is that each middle is a minimum or maximum value, and then he becomes a swap (which is worse because recursion is used). But how likely do you think this is going to happen? Oh, you don't have to worry about it at all. Practice has proved that in most cases, a quick sort is always the best.
If you're worried about this, you can use heap sorting, which is a stable O (log2 (n) *n) algorithm, but usually slower than fast sorting (because you want to regroup the heap).


It's been written several times these days, a continuous encounter on the common ranking algorithm stability discrimination, often or more, for me and I am as unsure of the students is not a subject to be easily concluded, of course, if you have already memorized the written data structure of the book which is stable, which is not stable, It should be easy to handle.

This article is intended for people who are always unable to remember this or want to really understand why it is stable or unstable.

First of all, the stability of the sorting algorithm we should all know, in layman's terms is to ensure that the first 2 equal number of the sequence before and after the order and after the ordering of the order of their two before and after the same position. In a simple formalization, if ai = AJ, Ai was originally in position, after the sort AI still to be in Aj position.

Second, talk about the benefits of stability. If the sort algorithm is stable, it is sorted from one key and then from another, and the result of the first key sort can be sorted by the second key. The Cardinal sort is this, first by the low order, successive orders by the high order, the lower the same level of the same sequence of the same will not change. In addition, if the sorting algorithm is stable, the number of element exchanges may be less (personal, unproven) for the comparison based sorting algorithm.

Back to the topic, now analyze the stability of the common sorting algorithm, each given a simple reason.

(1) Bubble sort

Bubble sort is to move small elements forward or to adjust the large elements backward. The comparison is a two-element comparison, and the exchange occurs between the two elements. So, if two elements are equal, I think you will not be bored to swap them out again; if two equal elements are not adjacent, then even if the previous 22 exchange to the two adjacent, this time will not be exchanged, so the same element before and after the order has not changed, so bubble sort is a stable sort algorithm.

(2) Select sort

The select sort is the smallest of the current element selected for each location, for example, for the first position to choose the smallest, in the remaining elements of the second element to select the second small, and so on, and so on, and so on, and so on, and so on, until the n-1 element, the nth element is not selected, because there is only one of the largest elements. Then, in a choice, if the current element is smaller than an element, and the small element appears behind an element that is equal to the current element, then the stability of the exchange is corrupted. Compared to a mouthful, for example, the sequence 5 8 5 2 9, we know that the first time to select the 1th element 5 and 2 Exchange, then the original sequence 2 5 of the relative order is destroyed, so the selection is not a stable sorting algorithm.

(3) Insert sort
The insertion sort is based on an already ordered small sequence that inserts one element at a time. Of course, at the beginning of this ordered sequence of only 1 elements, is the first element. The comparison begins at the end of the ordered sequence, where the element that you want to insert and the one that is already ordered is the one that is inserted directly behind it, if it is larger than it is, or until you find where it should be inserted. If you encounter an element that is equal to the insertion element, the insertion element places the elements that you want to insert behind the equality element. Therefore, the order of the equal elements is unchanged, the order from the original unordered sequence is the order after the sequence, so the insertion sort is stable.

(4) Quick Sort
The quick sort has two directions, the left I subscript goes right, and when A[i] <= A[center_index], where Center_index is the array subscript for the central element, typically the No. 0 element. And the J subscript on the right always goes left, when a[j] > A[center_index]. If I and J are not going to move, I <= J, swap A[i] and a[j], repeat the above process until i>j. Exchange A[j] and A[center_index] to complete a quick sort of a trip. When the central element and the a[j] exchange, it is possible to disrupt the stability of the elements in the front, for example, the sequence is 5 3 3 4 3 8 9 10 11, now the central elements 5 and 3 (the 5th element, subscript from 1) Exchange will disrupt the stability of element 3, so fast sorting is an unstable sort algorithm, Instability occurs at a time when central elements and a[j] exchange.

(5) Merge sort
Merge sort is to divide the sequence recursively into short sequences, the recursive exit is a short sequence with only 1 elements (considered direct order) or 2 sequences (1 comparisons and exchanges), and then merges each ordered sequence into an ordered long sequence, merging until the original sequence is all sorted out. It can be found that in 1 or 2 elements, 1 elements do not exchange, 2 elements if the size is equal and no one intentionally exchanged, this does not destroy stability. Then, in the process of merging short sequential sequences, the stability is destroyed. No, we can guarantee that if two current elements are equal, we keep the elements in the preceding sequence in front of the result sequence, which guarantees stability. Therefore, the merging sort is also a stable sorting algorithm.

(6) Cardinal order
The cardinality sort is sorted by the lows, then collected, sorted by high order, then collected, and so on until the highest bit. Sometimes some attributes are in order of precedence, first by low priority, and then by high priority, the final order is high priority in front, high priority of the same low priority high in the front. Base ordering is based on separate sorting and is collected separately, so it is a stable sort algorithm.

(7) Hill sort (shell)
Hill sorting is to insert the elements according to the different step size, when the first element is very disordered, the step is the largest, so the number of inserted sorted elements is very small, fast; When the elements are basically ordered, the step size is very low, the insertion order is efficient for ordered sequences. So the time complexity of hill sorting is better than O (n^2). Because of the multiple insertion sort, we know that a single insert sort is stable and does not change the relative order of the same elements, but in different inserts, the same elements may move in their respective insertion sort, and their stability will be disrupted, so the shell sort is unstable.

(8) Heap Sorting
We know that the structure of the heap is node I's child for 2*i and 2*I+1 nodes, the large top heap requires the parent node to be greater than or equal to its 2 subnodes, and the small top heap requires that the parent node be less than or equal to its 2 subnodes. In a sequence of long n, the process of heap sequencing is to select the maximum (large top heap) or the smallest (small top heap) with a total of 3 values from the beginning of N/2 and its child nodes, and the choice between these 3 elements certainly does not break the stability. But when for n/2-1, N/2-2, ... 1 When these parent nodes select elements, they break the stability. It is possible that the N/2 of the parent node swaps the subsequent element, while the n/2-1 parent node does not exchange the same element, then the stability between the 2 identical elements is corrupted. So, heap sort is not a stable sort algorithm


1 Quick Sort (QuickSort)

The quick sort is an in-place sequencing, divide-and-conquer, large-scale recursive algorithm. Essentially, it is the in-place version of the merge sort. The quick sort can consist of four steps below.

(1) If not more than 1 data, direct return.
(2) The leftmost value of the general selection sequence is used as fulcrum data.
(3) The sequence is divided into 2 parts, part of which is greater than fulcrum data, and the other part is less than Fulcrum data.
(4) A recursive sort sequence is used on both sides.

Fast sorting is faster than most sorting algorithms. Although we can write algorithms that are faster than fast sorting in some special cases, there is no faster than it usually does. The quick sort is recursive and is not a good choice for a machine with very limited memory.

2 Merge sort (mergesort)

The merge sort breaks down the sequence to be sorted first, from 1 to 2, 2 to 4, and then decomposed, which, when decomposed into only 1 groups, can be sorted and then merged back into the original sequence so that all the data can be sorted. The merge sort is a little faster than the heap sort, but it needs one more memory space than the heap sort, because it requires an extra array.

3 Heap sort (heapsort)

Heap sorting is suitable for situations where data is very large (millions of data).

Heap sorting does not require a large number of recursive or multidimensional staging arrays. This is appropriate for a very large number of data sequences. For example, more than millions of records, because the fast sort, merge sort all use the recursive design algorithm, when the data volume is very large, the stack overflow error may occur.

Heap sorting builds all the data into a heap, the largest data is on top of the heap, and then the heap top data is exchanged with the last data of the sequence. Then rebuild the heap again, swap the data, and sequentially, you can sort all the data.

4 Shell sort (shellsort)

The shell sort reduces the number of data exchanges and movements by dividing the data into groups, sorting each group first, and then inserting all the elements one at a time. The average efficiency is O (NLOGN). The rationality of the grouping will have an important influence on the algorithm. Now use the D.e.knuth grouping method more.

The shell sort is 5 times times faster than the bubble sort, roughly twice times faster than the insertion sort. Shell sorting is much slower than quicksort,mergesort,heapsort. But it is relatively simple, it is suitable for the data volume below 5000 and speed is not particularly important occasions. It is very good for the number of small data series to repeat the order.

5 Insertion Sort (insertsort)

Insert sort by inserting the values in a sequence into a sorted sequence until the end of the sequence. The insert sort is an improvement to the bubbling sort. It is twice times faster than bubble sort. It is generally not necessary to use insert sorting in cases where the data is greater than 1000, or to repeat the sequence of more than 200 data items.

6 Bubble sort (bubblesort)

Bubble sort is the slowest sort algorithm. In practical use it is the least efficient algorithm. It compares each element of the array by a Bandi and makes the larger data sink and the smaller data rise. It is an O (n^2) algorithm.

7 Switching sort (exchangesort) and selection sort (selectsort)

Both of these sorting methods are the sorting algorithm of the Exchange method, and the efficiency is all O (N2). In the actual application in and bubble sort basically the same status. They are only the initial stage of the sorting algorithm, which is less used in practice.

8 Cardinal Order (Radixsort)

Cardinality ordering and the usual sort algorithm do not follow the same route. It is a relatively novel algorithm, but it can only be used for the ordering of integers, if we're going to apply the same approach to floating-point numbers, we have to understand the storage format of floating-point numbers and map floating-point numbers to integers in a special way, and then map back again, which is a very cumbersome thing to do, so it's not much to use. And, most importantly, this algorithm also requires more storage space.

9 Summary

The following is a general table summarizing the characteristics of all the sorting algorithms that are common to us.

Sorting method Average Time Worst case scenario Degree of stability Extra Space Note
Bubble O (N2) O (N2) Stability O (1) N Hours is better
Exchange O (N2) O (N2) Unstable O (1) N Hours is better
Choose O (N2) O (N2) Unstable O (1) N Hours is better
Insert O (N2) O (N2) Stability O (1) Most of the sorted is better
Base O (LOGRB) O (LOGRB) Stability O (N)

B is the true number (0-9),

R is cardinality (1000)

Shell O (NLOGN) O (NS) 1<s<2 Unstable O (1) S is the selected group
Fast O (NLOGN) O (N2) Unstable O (NLOGN) n Good when Big
Merge O (NLOGN) O (NLOGN) Stability O (1) n Good when Big
Heap O (NLOGN) O (NLOGN) Unstable O (1) n Good when Big

The following is a generic sort based on a template:
This program I think there is no need for analysis, we can look at it. Do not understand can be asked on the forum.
MyData.h file
///////////////////////////////////////////////////////
Class CMyData
{
Public
CMyData (int index,char* strdata);
CMyData ();
Virtual ~cmydata ();

int m_iindex;
int Getdatasize () {return m_idatasize;};
Const char* GetData () {return m_strdatamember;};
Operators are overloaded here:
cmydata& operator = (CMyData &srcdata);
BOOL Operator < (cmydata& data);
BOOL operator > (cmydata& data);

Private
char* M_strdatamember;
int m_idatasize;
};
////////////////////////////////////////////////////////

MyData.cpp file
////////////////////////////////////////////////////////
Cmydata::cmydata ():
M_iindex (0),
M_idatasize (0),
M_strdatamember (NULL)
{
}

Cmydata::~cmydata ()
{
if (M_strdatamember!= NULL)
Delete[] M_strdatamember;
M_strdatamember = NULL;
}

Cmydata::cmydata (int index,char* strdata):
M_iindex (Index),
M_idatasize (0),
M_strdatamember (NULL)
{
M_idatasize = strlen (strdata);
M_strdatamember = new Char[m_idatasize+1];
strcpy (M_strdatamember,strdata);
}

cmydata& cmydata::operator = (cmydata &srcdata)
{
M_iindex = Srcdata.m_iindex;
M_idatasize = Srcdata.getdatasize ();
M_strdatamember = new Char[m_idatasize+1];
strcpy (M_strdatamember,srcdata.getdata ());
return *this;
}

BOOL Cmydata::operator < (cmydata& data)
{
Return m_iindex<data.m_iindex;
}

BOOL Cmydata::operator > (cmydata& data)
{
Return m_iindex>data.m_iindex;
}
///////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////
Main program Section
#include <iostream.h>
#include "MyData.h"

Template <class t>
void Run (t* pdata,int left,int right)
{
int i,j;
T middle,itemp;
i = left;
j = right;
The following comparisons call our overloaded operator function
Middle = pdata[(left+right)/2]; Find Middle Value
do{
while ((Pdata[i]<middle) && (i<right))//left-scan is greater than the median value
i++;
while ((Pdata[j]>middle) && (j>left))//scan from right is greater than the median value
j--;
if (I&LT;=J)//found a pair of values
{
Exchange
ITEMP = Pdata[i];
Pdata[i] = Pdata[j];
PDATA[J] = itemp;
i++;
j--;
}
}while (I&LT;=J)//If the subscript scanned on both sides is staggered, stop (once)

When the left part has a value (left<j), recursive left half
if (LEFT&LT;J)
Run (PDATA,LEFT,J);
When the right part has a value (right>i), recursive right half
if (right>i)
Run (pdata,i,right);
}

Template <class t>
void QuickSort (t* pdata,int Count)
{
Run (pdata,0,count-1);
}

void Main ()
{
CMyData data[] = {
CMyData (8, "xulion"),
CMyData (7, "Sanzoo"),
CMyData (6, "Wangjun"),
CMyData (5, "vckbase"),
CMyData (4, "jacky2000"),
CMyData (3, "cwally"),
CMyData (2, "Vcuser"),
CMyData (1, "Isdong")
};
QuickSort (data,8);
for (int i=0;i<8;i++)
cout<<data[i].m_iindex<< "" <<data[i]. GetData () << "/n";
cout<< "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.