Dowemo
0 0 0 0

We usually refer to the sort algorithm that's internal sorting algorithm, that's, data records are sorted in memory.

Sorting algorithms can be divided into two categories:

A comparison,, ~ n^2 ( ), is mainly: Bubble bubble,Choose sort,Insert sequence,Merging sort,Heap sequencing,Quick sortWait.

The other is , and the time complexity can reach o ( n ), mainly: In order to solve the problem, the order of is, and the of is.

Here we discuss the commonly used comparative sorting algorithms, and sorting algorithms will be introduced in the next article in . The following table shows the performance of common comparison sort algorithms:

It's very easy to ignore the stability of the algorithm (. ), which has been tested by.

The simple formal definition of the ranking algorithm is defined as: , if ai = retrying, sort before the ai before, after the sort of ai, the sort of ai is a stable,. is a common way to ensure that the relative order of two equal numbers before and after the ordering is.

For the unstable sorting algorithm, we can explain its instability as long as an example is given. For stable sorting algorithms, the algorithm must be analyzed and the stability of the algorithm. It's important to note whether the sorting algorithm is stable by the specific algorithm, and the unstable algorithm can become a stable algorithm under some condition.

For example, for the, a stable sorting algorithm, if the condition of the record exchange is changed to a [ I ]> = a [ I + 1 ], then the two equal records will be converted to an unstable ranking algorithm.

Second, the benefits of the ranking algorithm stability. The algorithm if it's stable, then sorts from one key and then sorts from another. The result of the first key sort can be sorted for the second key. In order to solve the problem, the order of the sequence isn't changed in the order of high order, and the order of the elements isn't changed.

( bubble sort )

is an extremely simple sort of algorithm, as well as my first sort algorithm. It repeatedly accesses the elements, compares the adjacent two elements, and then switches them back if they're wrong, until no elements need to be exchanged. The name of this algorithm is because the smaller ( or bigger ) elements will be slowly"floating"to the top of the sequence.

The algorithm operates as follows:

  • Compare adjacent elements, and if the previous one is larger than the latter, they're replaced.
  • For each pair of adjacent elements, the last pair from the beginning to the end. After that, the last element will be the maximum number.
  • Repeat the above steps for all elements except the last.
  • Continuously repeat the above steps for fewer elements until no pair of numbers need to be compared.

Because of its simplicity, the is often used to introduce the concept of the algorithm. The code is as follows:

复制代码
#include <stdio.h>// 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(n^2)// 最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,可以把最优时间复杂度降低到O(n)// 平均时间复杂度 ---- O(n^2)// 所需辅助空间 ------ O(1)// 稳定性 ------------ 稳定void Swap(int A[], int i, int j)
{
 int temp = A[i];
 A[i] = A[j];
 A[j] = temp;
}void BubbleSort(int A[], int n)
{
 for (int j = 0; j <n - 1; j++) // 每次最大元素就像气泡一样"浮"到数组的最后 {
 for (int i = 0; i <n - 1 - j; i++) // 依次比较相邻的两个元素,使较大的那个向后移 {
 if (A[i]> A[i + 1]) // 如果条件改成A[i]> = A[i + 1],则变为不稳定的排序算法 {
 Swap(A, i, i + 1);
 }
 }
 }
}int main()
{
 int A[] = { 6, 5, 3, 1, 8, 7, 2, 4 }; // 从小到大冒泡排序int n = sizeof(A)/sizeof(int);
 BubbleSort(A, n);
 printf("冒泡排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

In the above code, the sequence of %, 5, 3, 1, 8, microformats, 2, 4..............

A process that uses bubble to sort a column of numbe &, as shown on the right:

Although is one of the most easy to understand and implement, it isn't efficient to sort a sequence of numbers outside of a few elements.

Improvement of bubble bubble:

In order to improve the performance of, it's an improvement of the. The difference between the algorithm and the bubble is from low to high and from high to low, and the bubble is only from low to high to compare every element in. He can get a better performance than the bubble.

The code is the following:

复制代码
#include <stdio.h>// 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(n^2)// 最优时间复杂度 ---- 如果序列在一开始已经大部分排序过的话,会接近O(n)// 平均时间复杂度 ---- O(n^2)// 所需辅助空间 ------ O(1)// 稳定性 ------------ 稳定void Swap(int A[], int i, int j)
{
 int temp = A[i];
 A[i] = A[j];
 A[j] = temp;
}void CocktailSort(int A[], int n)
{
 int left = 0; // 初始化边界int right = n - 1;
 while (left < right)
 {
 for (int i = left; i <right; i++) // 前半轮,将最大元素放到后面 {
 if (A[i]> A[i + 1])
 {
 Swap(A, i, i + 1);
 }
 }
 right--;
 for (int i = right; i> left; i--) // 后半轮,将最小元素放到前面 {
 if (A[i - 1]>  A[i])
 {
 Swap(A, i - 1, i);
 }
 }
 left++;
 }
}int main()
{
 int A[] = { 6, 5, 3, 1, 8, 7, 2, 4 }; // 从小到大定向冒泡排序int n = sizeof(A)/sizeof(int);
 CocktailSort(A, n);
 printf("鸡尾酒排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

The process of sorting a number for a column using is as follows:

For example, ( 2, 3, 4, 5, 1 ) for example, ordering can complete ordering only if you've access to a sequence of colum &, but you need four times if you use bubbles. But in the state of sequence, the efficiency of and is very bad.

selection sort ( select sort )

Choosing sort is also a simple and intuitive sort algorithm. Its working principle is easy to understand: The minimum ( large ) element is found in the sequence, and placed in the beginning of the sequence as a sorted sequence; Then, continue looking for minimal ( large ) elements from the remaining unordered elements and put them at the end of the sorted sequence. So, until all elements are sorted.

Note the differences between sorting and bubble selection: In order to put the current minimum ( large ) element in the appropriate position, the of the two sequences isn't valid. The choice of sorting is to remember the position of the current minimum ( large ) element at a time, and at the end of a swap operation can be placed in the appropriate position.

Select sortThe code is as follows:

复制代码
#include <stdio.h>// 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(n^2)// 最优时间复杂度 ---- O(n^2)// 平均时间复杂度 ---- O(n^2)// 所需辅助空间 ------ O(1)// 稳定性 ------------ 不稳定void Swap(int A[], int i, int j)
{
 int temp = A[i];
 A[i] = A[j];
 A[j] = temp;
}void SelectionSort(int A[], int n)
{
 for (int i = 0; i <n - 1; i++) // i为已排序序列的末尾 {
 int min = i;
 for (int j = i + 1; j <n; j++) // 未排序序列 {
 if (A[j] <A[min]) // 找出未排序序列中的最小值 {
 min = j;
 }
 }
 if (min!= i)
 {
 Swap(A, min, i); // 放到已排序序列的末尾,该操作很有可能把稳定性打乱,所以选择排序是不稳定的排序算法 }
 }
}int main()
{
 int A[] = { 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 }; // 从小到大选择排序int n = sizeof(A)/sizeof(int);
 SelectionSort(A, n);
 printf("选择排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

A %, 5, 2, 6, 9, microformats, 4. 0. 7,...............

Use selection to sort a macro process for a column of numbe &:

selection sorting is an unstable sorting algorithm, which isn't stable at the moment of the minimum element and a [.

such as sequence: % 7b 5 8, 5 , 2 In 9. The smallest element selected is, then 2 and first 5 are exchanged, thus changing the relative order of two elements 5.

( insertion sort )

Inserted order is a simple and intuitive sort algorithm. Its working principle is very similar to our playing card.

For data ( cards ), in the sorted sequence ( the left hand already arranged on the hand ) from the back to the back, locate the corresponding position.

In the implementation, in place is usually used to sort ( I. E. Only to o ( 1 ) ), so that the sorted elements need to be moved backward backward, and I.

The specific algorithm describes the following:

  • Beginning with the first element, the element can be considered
  • Take the next element and scan it backwards from the sequence of elements already sorted
  • If the element ( sorted ) is greater than the new element, move the element to the next location
  • Repeat step 3 until a sorted element is found less than or equal to a new element
  • After inserting new elements into this location
  • Repeat step 2 ~ 5

The code for inserting rows is as follows:

复制代码
#include <stdio.h>// 分类 ------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2)// 最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n)// 平均时间复杂度 ---- O(n^2)// 所需辅助空间 ------ O(1)// 稳定性 ------------ 稳定void InsertionSort(int A[], int n)
{
 for (int i = 1; i <n; i++) // 类似抓扑克牌排序 {
 intget = A[i]; // 右手抓到一张扑克牌int j = i - 1; // 拿在左手上的牌总是排序好的while (j> = 0 && A[j]> get) // 将抓到的牌与手牌从右向左进行比较 {
 A[j + 1] = A[j]; // 如果该手牌比抓到的牌大,就将其右移 j--;
 }
 A[j + 1] = get; // 直到该手牌比抓到的牌小(或二者相等),将抓到的牌插入到该手牌右边(相等元素的相对次序未变,所以插入排序是稳定的) }
}int main()
{
 int A[] = { 6, 5, 3, 1, 8, 7, 2, 4 };// 从小到大插入排序int n = sizeof(A)/sizeof(int);
 InsertionSort(A, n);
 printf("插入排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

In the above code, the implementation process of inserting a sequence of 6, 5, 3, 1, 8. 2, 4. %.

A macro process that uses interpolation to sort a number of digits:

ordering isn't suitable for sorting applications with large amount of data. However, if the amount of data you need to sort is small, such as the order of magnitude less than kilobytes, then the insertion sequence is a good choice. In the library, the sequence is widely used in the industrial stage. In the stdlib 's qsort algorithm and the algorithm of.

Improvement in sequence: Binary interpolation sequence

If the cost of the comparison is larger than that of the operation, the method can be used to reduce the number of comparison operations,

复制代码
#include <stdio.h>// 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(n^2)// 最优时间复杂度 ---- O(nlogn)// 平均时间复杂度 ---- O(n^2)// 所需辅助空间 ------ O(1)// 稳定性 ------------ 稳定void InsertionSortDichotomy(int A[], int n)
{
 for (int i = 1; i <n; i++)
 {
 intget = A[i]; // 右手抓到一张扑克牌int left = 0; // 拿在左手上的牌总是排序好的,所以可以用二分法int right = i - 1; // 手牌左右边界进行初始化while (left <= right) // 采用二分法定位新牌的位置 {
 int mid = (left + right)/2;
 if (A[mid]> get)
 right = mid - 1;
 else left = mid + 1;
 }
 for (int j = i - 1; j> = left; j--) // 将欲插入新牌位置右边的牌整体向右移动一个单位 {
 A[j + 1] = A[j];
 }
 A[left] = get; // 将抓到的牌插入手牌 }
}int main()
{
 int A[] = { 5, 2, 9, 4, 7, 6, 1, 3, 8 };// 从小到大二分插入排序int n = sizeof(A)/sizeof(int);
 InsertionSortDichotomy(A, n);
 printf("二分插入排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

When n is larger, the number of successive interpolation orders is better than that of direct insertion sequence, but it's better than directly inserted into the The number of elements moved in the same order as direct insertion, dependent on the initial sequence.

A more efficient improvement in sequence: Hill sorting ( shell sort )

Hill sorting, also called incremental sort, is a more efficient version of the input sequence. Hill sorting is the sort algorithm of.

Hill sort is an improved method based on the following two characteristics of inserted sequence:

  • In order to improve the efficiency of linear sorting, it's very efficient to the data operation in order to meet.
  • However, the insertion sequence is usually inefficient because the insertion sequence can only move one one at a time.

Hill sorting improves the performance of the insertion sequence by dividing all the elements of the comparison into several areas. This allows an element to move forward to the final position at a time. Then the algorithm is sorted by smaller step size. The final step of the algorithm is normal insertion sequence, but the data that needs to be sorted is almost.
Assume that there's a small data at the end of an array that has been sorted in ascending order. If you use a sort of complexity o ( n^2 ), the sort of or, the n comparison and exchange can be performed to move the data to the correct position. While hill sorting uses a larger step of moving data, small data can only be compared and exchanged to the correct position.

The code for hill sort is as follows:

复制代码
#include <stdio.h> // 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- 根据步长序列的不同而不同。已知最好的为O(n(logn)^2)// 最优时间复杂度 ---- O(n)// 平均时间复杂度 ---- 根据步长序列的不同而不同。// 所需辅助空间 ------ O(1)// 稳定性 ------------ 不稳定void ShellSort(int A[], int n)
{
 int h = 0;
 while (h <= n) // 生成初始增量 {
 h = 3 * h + 1;
 }
 while (h> = 1)
 {
 for (int i = h; i <n; i++)
 {
 int j = i - h;
 intget = A[i];
 while (j> = 0 && A[j]> get)
 {
 A[j + h] = A[j];
 j = j - h;
 }
 A[j + h] = get;
 }
 h = (h - 1)/3; // 递减增量 }
}int main()
{
 int A[] = { 5, 2, 9, 4, 7, 6, 1, 3, 8 };// 从小到大希尔排序int n = sizeof(A)/sizeof(int);
 ShellSort(A, n);
 printf("希尔排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

sequences with 23, 10, 4, 1:

sorting is an unstable sorting algorithm, while is stable, it doesn't change the relative order of the same elements, but the same elements can be.

such as sequence: % 3, 5, 10, 8 7, 2, 8 1, 20, 6 %, h = 2 is divided into two % 7b, 10, 7. 8 20 % 5 and %, 8 2, 1, 6 % referrals, in the second subsequence column before sorting, now the two subsequence columns are inserted into the row order, and the % s 7,8,1020 % 7d and %.1,2,5,6,8%, 3, 1, 7, 2. %. 8 5, 10, 6, 20, 8 In %, the relative order of two 8 is changed.

Merge sort with ( merge sort )

Merging sort is an effective sort algorithm to create in the merging operation. The efficiency is o ( nlogn ), which is the first time in 1945.

The implementation of merging sort is divided into recursive implementation and ( iterative ) implementation. The merging sort of recursive implementation is a typical application in the algorithm design. We divide a large problem into smaller problems, then solve the. The merging sort of ( iterative ) implementation first is merging, then four merging, then eight merging, until the entire array.

Merging sorting algorithms mainly rely on merging ( merge ) operations. Merge operations refer to the combination of two sorted sequences into a sequence of operations, and the operation steps are as follows:

  • In order to store the merged sequence, the application space is to the sum of two sorted sequences.
  • Sets two pointers, starting at the beginning of two sorted sequences
  • Compare the elements that are pointing to the two pointers, select a relatively small element into the merged space, and move the pointer to the next location
  • Repeat step 3 until a pointer reaches the end of the sequence
  • Copy all the remaining elements of another sequence directly to the merge sequence tail

Merging sorts of code is as follows:

复制代码
#include <stdio.h>#include <limits.h>// 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(nlogn)// 最优时间复杂度 ---- O(nlogn)// 平均时间复杂度 ---- O(nlogn)// 所需辅助空间 ------ O(n)// 稳定性 ------------ 稳定void Merge(int A[], int left, int mid, int right)// 合并两个已排好序的数组A[left...mid]和A[mid+1...right]{
 int len = right - left + 1;
 int *temp = newint[len]; // 辅助空间O(n)int index = 0;
 int i = left; // 前一数组的起始元素int j = mid + 1; // 后一数组的起始元素while (i <= mid && j <= right)
 {
 temp[index++] = A[i] <= A[j]? A[i++] : A[j++]; // 带等号保证归并排序的稳定性 }
 while (i <= mid)
 {
 temp[index++] = A[i++];
 }
 while (j <= right)
 {
 temp[index++] = A[j++];
 }
 for (int k = 0; k <len; k++)
 {
 A[left++] = temp[k];
 }
}void MergeSortRecursion(int A[], int left, int right) // 递归实现的归并排序(自顶向下){
 if (left == right) // 当待排序的序列长度为1时,递归开始回溯,进行merge操作return;
 int mid = (left + right)/2;
 MergeSortRecursion(A, left, mid);
 MergeSortRecursion(A, mid + 1, right);
 Merge(A, left, mid, right);
}void MergeSortIteration(int A[], int len) // 非递归(迭代)实现的归并排序(自底向上){
 int left, mid, right;// 子数组索引,前一个为A[left...mid],后一个子数组为A[mid+1...right]for (int i = 1; i <len; i *= 2) // 子数组的大小i初始为1,每轮翻倍 {
 left = 0;
 while (left + i <len) // 后一个子数组存在(需要归并) {
 mid = left + i - 1;
 right = mid + i <len? mid + i : len - 1;// 后一个子数组大小可能不够 Merge(A, left, mid, right);
 left = right + 1; // 前一个子数组索引向后移动 }
 }
}int main()
{
 int A1[] = { 6, 5, 3, 1, 8, 7, 2, 4 }; // 从小到大归并排序int A2[] = { 6, 5, 3, 1, 8, 7, 2, 4 };
 int n1 = sizeof(A1)/sizeof(int);
 int n2 = sizeof(A2)/sizeof(int);
 MergeSortRecursion(A1, 0, n1 - 1); // 递归实现 MergeSortIteration(A2, n2); // 非递归实现 printf("递归实现的归并排序结果:");
 for (int i = 0; i <n1; i++)
 {
 printf("%d ", A1[i]);
 }
 printf("n");
 printf("非递归实现的归并排序结果:");
 for (int i = 0; i <n2; i++)
 {
 printf("%d ", A2[i]);
 }
 printf("n");
 return0;
}
复制代码

Examples of the above code are % 6, 5, 3, 1, 8, microformats, 2, 4..............,,,,.

A macro process that uses merge sort to sort a column of numbe &:

Merging sorting can be done in addition to the array, and can efficiently calculate the array small and ( and ) as well as the reve & e of the array, as shown in this blog post.

stack sequence ( heap sort )

Heap sequencing refers to a selection sort algorithm designed by using the heap data structure. A heap is a structure that's approximate to a completely complete binary tree ( usually a heap is implemented through a array ) and meets the properties: For example, the largest heap ( also known as big heap, large heap ), where the value of the parent node is always greater than its child node.

We can easily define the process of heap sequencing:

  • Co tructs a maximum heap by the unordered array entered as an initial unordered region
  • Swap the top element ( maximum ) and the heap tail element
  • Reduce the size of the heap ( ) to 1 and call heapify ( a, 0 ) from the new heap top element
  • Repeat step 2 until the heap size is 1

The code for the heap sequence is as follows:

复制代码
#include <stdio.h>// 分类 -------------- 内部比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(nlogn)// 最优时间复杂度 ---- O(nlogn)// 平均时间复杂度 ---- O(nlogn)// 所需辅助空间 ------ O(1)// 稳定性 ------------ 不稳定void Swap(int A[], int i, int j)
{
 int temp = A[i];
 A[i] = A[j];
 A[j] = temp;
}void Heapify(int A[], int i, int size) // 从A[i]向下进行堆调整{
 int left_child = 2 * i + 1; // 左孩子索引int right_child = 2 * i + 2; // 右孩子索引int max = i; // 选出当前结点与其左右孩子三者之中的最大值if (left_child <size && A[left_child]>  A[max])
 max = left_child;
 if (right_child <size && A[right_child]>  A[max])
 max = right_child;
 if (max!= i)
 {
 Swap(A, i, max); // 把当前结点和它的最大(直接)子节点进行交换 Heapify(A, max, size); // 递归调用,继续从当前结点向下进行堆调整 }
}int BuildHeap(int A[], int n) // 建堆,时间复杂度O(n){
 int heap_size = n;
 for (int i = heap_size/2 - 1; i> = 0; i--) // 从每一个非叶结点开始向下进行堆调整 Heapify(A, i, heap_size);
 return heap_size;
}void HeapSort(int A[], int n)
{
 int heap_size = BuildHeap(A, n); // 建立一个最大堆while (heap_size> 1)        // 堆(无序区)元素个数大于1,未完成排序 {
 // 将堆顶元素与堆的最后一个元素互换,并从堆中去掉最后一个元素
 // 此处交换操作很有可能把后面元素的稳定性打乱,所以堆排序是不稳定的排序算法 Swap(A, 0, --heap_size);
 Heapify(A, 0, heap_size); // 从新的堆顶元素开始向下进行堆调整,时间复杂度O(logn) }
}int main()
{
 int A[] = { 5, 2, 9, 4, 7, 6, 1, 3, 8 };// 从小到大堆排序int n = sizeof(A)/sizeof(int);
 HeapSort(A, n);
 printf("堆排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

Demo of the algorithm:

The process of creating a heap, as well as the logical structure of the heap, is simple before the sorting process.

sequencing is an unstable sorting algorithm, which isn't stable at the top of the heap top element and a [ I ].

such as sequence: % 7b 9, 5 7, 5 %, the heap top element is 9, the heap sequence next step to swap 9 and second 5 to get the sequence %. 5 , 5 7, 9 % referrals, and then heap adjustments get % 7b 7, 5 , 5 In 9 %, the previous operation was finally obtained by %. 5 , 5 7, 9 % referrals to change the relative order of two 5.

Fast sorting ( quick sort )

Fast sorting is a sort of sort algorithm developed by · hall. In average, the sorting n elements are to be compared to the o. In the worst situation, we need o ( n^2 ) comparison, but this isn't common. In fact, fast sorting is usually faster than other o ( tam ) algorithms, because its internal loop can be implemented in most of the architectures efficiently.

Fast sorting uses the divide and conquer ( divide ) to divide one sequence into two columns. Steps are:

  • Pick an element from the sequence column as a baseline ( pivot ).
  • Place all elements that are smaller than the base value, and all the elements that are larger than the base value are placed behind the benchmark ( the same number can be.
  • For each partition recursively step 1 ~ 2, the end condition of recursion is either 0 or 1, and the whole has been sorted in order.

The quick sort code is as follows:

复制代码
#include <stdio.h>// 分类 ------------ 内部比较排序// 数据结构 --------- 数组// 最差时间复杂度 ---- 每次选取的基准都是最大(或最小)的元素,导致每次只划分出了一个分区,需要进行n-1次划分才能结束递归,时间复杂度为O(n^2)// 最优时间复杂度 ---- 每次选取的基准都是中位数,这样每次都均匀的划分出两个分区,只需要logn次划分就能结束递归,时间复杂度为O(nlogn)// 平均时间复杂度 ---- O(nlogn)// 所需辅助空间 ------ 主要是递归造成的栈空间的使用(用来保存left和right等局部变量),取决于递归树的深度,一般为O(logn),最差为O(n) // 稳定性 ---------- 不稳定void Swap(int A[], int i, int j)
{
 int temp = A[i];
 A[i] = A[j];
 A[j] = temp;
}int Partition(int A[], int left, int right) // 划分函数{
 int pivot = A[right]; // 这里每次都选择最后一个元素作为基准int tail = left - 1; // tail为小于基准的子数组最后一个元素的索引for (int i = left; i <right; i++) // 遍历基准以外的其他元素 {
 if (A[i] <= pivot) // 把小于等于基准的元素放到前一个子数组末尾 {
 Swap(A, ++tail, i);
 }
 }
 Swap(A, tail + 1, right); // 最后把基准放到前一个子数组的后边,剩下的子数组既是大于基准的子数组
 // 该操作很有可能把后面元素的稳定性打乱,所以快速排序是不稳定的排序算法return tail + 1; // 返回基准的索引}void QuickSort(int A[], int left, int right)
{
 if (left> = right)
 return;
 int pivot_index = Partition(A, left, right); // 基准的索引 QuickSort(A, left, pivot_index - 1);
 QuickSort(A, pivot_index + 1, right);
}int main()
{
 int A[] = { 5, 2, 9, 4, 7, 6, 1, 3, 8 }; // 从小到大快速排序int n = sizeof(A)/sizeof(int);
 QuickSort(A, 0, n - 1);
 printf("快速排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

Use quick sort to sort a column of numbe &:

fast sorting is an unstable sorting algorithm, which occurs at the moment of the base element and a [ tail + 1 ].

such as sequence: % 1, 3, 4, 2, 8 9, 8 7, 5 7d, the reference element is, after a partition operation 5 to be exchanged with the fi t 8, thus changing the relative order of two elements 8.

The array. Sort function provided by the java system. For the underlying type, the underlying use of a quick sort. For types, the underlying use merge sort. Why are you.

Answer: this is the stability of the sort algorithm. For the base type, the same value is no difference, and the relative position of the same value before and after sorting isn't important, so it's a more efficient For the type, the relative position of the equal I & tance before and after sorting isn't changed, so choosing a stable merging sort.


We summarize the commonly used sorting algorithms, which mainly have..

Let's explore the commonly used sorting algorithms: In order to solve the problem, the sequence is, and the of the is. Under certain conditions, their time complexity can reach o ( n ).

The only data structure we use here's arrays, and we can also use lists to implement the following algorithms.

( counting sort )

The count sort uses an extra count array c, which causes the elements in the original array a to be transferred to the correct location.

for example, with 10 age different people, if you count out the age of 8 people isn't too large ( that's, it's less than bob 's age, which is. Of course, you need special processing when age is the same ( guaranteed stability ): By the target array, the corresponding numeric statistics decrease after filling, which can ensure the stability of order.

The count sort steps are as follows:

  • Count the number of [ I ] for each value in the array a, and save the [ a [ I ] ]
  • After the former, each value in the array c is equal to the previous one, so the array c [ a [ I ] ] becomes the number of elements that represent the number of elements that are less than the I in an array a
  • target array b: In [ [ a [ I ] ] location ( subscript as c [ a [ I ] ] ), the array element a I ] is placed on the a I of the array b.

The implementation code for the count sort is as follows:

复制代码
#include<iostream>usingnamespace std;// 分类 ------------ 内部非比较排序// 数据结构 --------- 数组// 最差时间复杂度 ---- O(n + k)// 最优时间复杂度 ---- O(n + k)// 平均时间复杂度 ---- O(n + k)// 所需辅助空间 ------ O(n + k)// 稳定性 ----------- 稳定constint k = 100; // 基数为100,排序[0,99]内的整数int C[k]; // 计数数组void CountingSort(int A[], int n)
{
 for (int i = 0; i <k; i++) // 初始化,将数组C中的元素置0(此步骤可省略,整型数组元素默认值为0) {
 C[i] = 0;
 }
 for (int i = 0; i <n; i++) // 使C[i]保存着等于i的元素个数 {
 C[A[i]]++;
 }
 for (int i = 1; i <k; i++) // 使C[i]保存着小于等于i的元素个数,排序后元素i就放在第C[i]个输出位置上 {
 C[i] = C[i] + C[i - 1];
 }
 int *B = (int *)malloc((n) * sizeof(int));// 分配临时空间,长度为n,用来暂存中间数据for (int i = n - 1; i> = 0; i--) // 从后向前扫描保证计数排序的稳定性(重复元素相对次序不变) {
 B[--C[A[i]]] = A[i]; // 把每个元素A[i]放到它在输出数组B中的正确位置上
 // 当再遇到重复元素时会被放在当前元素的前一个位置上保证计数排序的稳定性 }
 for (int i = 0; i <n; i++) // 把临时空间B中的数据拷贝回A {
 A[i] = B[i];
 }
 free(B); // 释放临时空间 }int main()
{
 int A[] = { 15, 22, 19, 46, 27, 73, 1, 19, 8 }; // 针对计数排序设计的输入,每一个元素都在[0,100]上且有重复元素int n = sizeof(A)/sizeof(int);
 CountingSort(A, n);
 printf("计数排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

A simple demonstration procedure for counting % 7b, 1, 3, 4, 3 % referrals

Counts the time complexity and space complexity of the sort sort and the range of the array a ( the maximum value in a element with the minimum value of the smallest value ), so the is a large array of time and memory, and the count sort requires a large amount of time and memory.

For example, the number of 0 to 99 is sorted, counting is the best algorithm. However, counting isn't suitable for ordering names in alphabetical order.

sequence ( radix sort )

The invention of the sequence can be traced back to 1887 · in the punch card manufacturing machine. It's implemented as follows: Uniform positive integers are uniform to the same digit length, with a shorter number of digits before zero. Then, the number of digits from the lowest level to 10 is sorted, until the highest bit count is sorted, the sequence becomes an ordered sequence ( with the stability of the count sort ).

The implementation code for the sequence is as follows:

复制代码
#include<iostream>usingnamespace std;// 分类 ------------- 内部非比较排序// 数据结构 ---------- 数组// 最差时间复杂度 ---- O(n * dn)// 最优时间复杂度 ---- O(n * dn)// 平均时间复杂度 ---- O(n * dn)// 所需辅助空间 ------ O(n * dn)// 稳定性 ----------- 稳定constint dn = 3; // 待排序的元素为三位数及以下constint k = 10; // 基数为10,每一位的数字都是[0,9]内的整数int C[k];int GetDigit(int x, int d) // 获得元素x的第d位数字{
 int radix[] = { 1, 1, 10, 100 };// 最大为三位数,所以这里只要到百位就满足了return (x/radix[d]) % 10;
}void CountingSort(int A[], int n, int d)// 依据元素的第d位数字,对A数组进行计数排序{
 for (int i = 0; i <k; i++)
 {
 C[i] = 0;
 }
 for (int i = 0; i <n; i++)
 {
 C[GetDigit(A[i], d)]++;
 }
 for (int i = 1; i <k; i++)
 {
 C[i] = C[i] + C[i - 1];
 }
 int *B = (int*)malloc(n * sizeof(int));
 for (int i = n - 1; i> = 0; i--)
 {
 int dight = GetDigit(A[i], d); // 元素A[i]当前位数字为dight  B[--C[dight]] = A[i]; // 根据当前位数字,把每个元素A[i]放到它在输出数组B中的正确位置上
 // 当再遇到当前位数字同为dight的元素时,会将其放在当前元素的前一个位置上保证计数排序的稳定性 }
 for (int i = 0; i <n; i++)
 {
 A[i] = B[i];
 }
 free(B);
}void LsdRadixSort(int A[], int n) // 最低位优先基数排序{
 for (int d = 1; d <= dn; d++) // 从低位到高位 CountingSort(A, n, d); // 依据第d位数字对A进行计数排序}int main()
{
 int A[] = { 20, 90, 64, 289, 998, 365, 852, 123, 789, 456 };// 针对基数排序设计的输入int n = sizeof(A)/sizeof(int);
 LsdRadixSort(A, n);
 printf("基数排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

In the following illustration, we give a simple demonstration procedure for the sequence ordering of % 7b, 457, 657, 839, 436, 720,

The time complexity of the base number is o ( n ) *dnwhere n is the number of elements to be sorted, the dn is the number number. This time complexity isn't necessarily better than o ( n log n ), the size of the dn depends on the number of digits ( such as bit bits ), and the overall size of the data types to be sorted; The dn determines how many wheels are processed and n is the number of operations.

If we consider and compare the sorting, the form complexity of the base number isn't necessarily smaller, but because it isn't compared, it's less expensive, and. Because an integer can also express a string ( such as a name or date ) and a floating point, the base number sequence isn't intended to be.

( bucket sort )

Bucket sort also called box sort. The principle of the work is to map the array elements to a finite number of buckets, using counting sort to position the bucket 's boundaries, each bucket is sorted.

The implementation code for the bucket sort is as follows:

复制代码
#include<iostream>usingnamespace std;// 分类 ------------- 内部非比较排序// 数据结构 --------- 数组// 最差时间复杂度 ---- O(nlogn)或O(n^2),只有一个桶,取决于桶内排序方式// 最优时间复杂度 ---- O(n),每个元素占一个桶// 平均时间复杂度 ---- O(n),保证各个桶内元素个数均匀即可// 所需辅助空间 ------ O(n + bn)// 稳定性 ----------- 稳定/* 本程序用数组模拟桶 */constint bn = 5; // 这里排序[0,49]的元素,使用5个桶就够了,也可以根据输入动态确定桶的数量int C[bn]; // 计数数组,存放桶的边界信息void InsertionSort(int A[], int left, int right)
{
 for (int i = left + 1; i <= right; i++) // 从第二张牌开始抓,直到最后一张牌 {
 intget = A[i];
 int j = i - 1;
 while (j> = left && A[j]> get)
 {
 A[j + 1] = A[j];
 j--;
 }
 A[j + 1] = get;
 }
}int MapToBucket(int x)
{
 return x/10; // 映射函数f(x),作用相当于快排中的Partition,把大量数据分割成基本有序的数据块}void CountingSort(int A[], int n)
{
 for (int i = 0; i <bn; i++)
 {
 C[i] = 0;
 }
 for (int i = 0; i <n; i++) // 使C[i]保存着i号桶中元素的个数 {
 C[MapToBucket(A[i])]++;
 }
 for (int i = 1; i <bn; i++) // 定位桶边界:初始时,C[i]-1为i号桶最后一个元素的位置 {
 C[i] = C[i] + C[i - 1];
 }
 int *B = (int *)malloc((n) * sizeof(int));
 for (int i = n - 1; i> = 0; i--)// 从后向前扫描保证计数排序的稳定性(重复元素相对次序不变) {
 int b = MapToBucket(A[i]); // 元素A[i]位于b号桶 B[--C[b]] = A[i]; // 把每个元素A[i]放到它在输出数组B中的正确位置上
 // 桶的边界被更新:C[b]为b号桶第一个元素的位置 }
 for (int i = 0; i <n; i++)
 {
 A[i] = B[i];
 }
 free(B);
}void BucketSort(int A[], int n)
{
 CountingSort(A, n); // 利用计数排序确定各个桶的边界(分桶)for (int i = 0; i <bn; i++) // 对每一个桶中的元素应用插入排序 {
 int left = C[i]; // C[i]为i号桶第一个元素的位置int right = (i == bn - 1? n - 1 : C[i + 1] - 1);// C[i+1]-1为i号桶最后一个元素的位置if (left <right) // 对元素个数大于1的桶进行桶内插入排序 InsertionSort(A, left, right);
 }
}int main()
{
 int A[] = { 29, 25, 3, 49, 9, 37, 21, 43 };// 针对桶排序设计的输入int n = sizeof(A)/sizeof(int);
 BucketSort(A, n);
 printf("桶排序结果:");
 for (int i = 0; i <n; i++)
 {
 printf("%d ", A[i]);
 }
 printf("n");
 return0;
}
复制代码

In the following illustration, a simple demonstration process for the scheduling of %, 25, 3, 49, 9. 21, 43.

Bucket sort isn't a sort of comparison, and isn't affected by the lower bound of o ( tam ), which is an inductive result of sorting, and the bucket sort has linear time complexity when the array value to be sorted is evenly distributed.







Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs