Algorithm | Sort
Bubble sort
Bubble sort, sometimes incorrectly referred to as sinking sort, is a simple sorting algorithm that works by repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm gets its name from the way smaller elements "bubble" to the top of the list. Because it only uses comparisons to operate on elements, it is a comparison sort. Although the algorithm is simple, most of the other sorting algorithms are more efficient for large lists.
Selection sort
selection sort is a sorting algorithm, specifically an in-place comparison sort. It has O(n2) time complexity, making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort is noted for its simplicity, and it has performance advantages over more complicated algorithms in certain situations, particularly where auxiliary memory is limited.
The algorithm divides the input list into two parts: the sublist of items already sorted, which is built up from left to right at the front (left) of the list, and the sublist of items remaining to be sorted that occupy the rest of the list. Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist, exchanging it with the leftmost unsorted element (putting it in sorted order), and moving the sublist boundaries one element to the right.
Heapsort
Heapsort is a comparison-based sorting algorithm. Heapsort is part of the selection sort family; it improves on the basic selection sort by using a logarithmic-time priority queue rather than a linear-time search. Although somewhat slower in practice on most machines than a well-implemented quicksort, it has the advantage of a more favorable worst-case O(n log n) runtime. Heapsort is an in-place algorithm, but it is not a stable sort.
The heapsort algorithm can be divided into two parts.
In the first step, a heap is built out of the data. The heap is often placed in an array with the layout of a complete binary tree. The complete binary tree maps the binary tree structure into the array indices; each array index represents a node; the index of the node's parent, left child branch, or right child branch are simple expressions. For a zero-based array, the root node is stored at index 0; if i is the index of the current node, then
iParent = floor((i-) / )
iLeftChild = *i +
iRightChild = *i +
建堆的开销是O(n)。这个是可以证明的。
从倒数第二层往上建堆,假设堆高为h,那么第h-1层有\(2^{h-2}\)个结点,需要调整1次。第h-i层有\(2^{h - i - 1}\)个结点,需要调整i次。所以整个开销就是:
\(1 \times 2^{h-2} + 2 \times 2^{h -3} + \cdots + (h - 1) \times 2^0\) ,拆成多个等比序列,然后用等比序列的求和公式可以得到结果为
\( 2^h - h - 1\), 因为h=O(lgn),所以结果应该就是O(n).
In the second step, a sorted array is created by repeatedly removing the largest element from the heap (the root of the heap), and inserting it into the array. The heap is updated after each removal to maintain the heap. Once all objects have been removed from the heap, the result is a sorted array. Heapsort can be performed in place. The array can be split into two parts, the sorted array and the heap.
Insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. However, insertion sort provides several advantages:
- Simple implementation
- Efficient for (quite) small data sets
- Adaptive (i.e., efficient) for data sets that are already substantially sorted: the time complexity is O(n + d), where d is the number of inversions
- More efficient in practice than most other simple quadratic (i.e., O(n2)) algorithms such as selection sort or bubble sort; the best case (nearly sorted input) is O(n)
- Stable; i.e., does not change the relative order of elements with equal keys
- In-place; i.e., only requires a constant amount O(1) of additional memory space
- Online; i.e., can sort a list as it receives it
Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.
Quicksort
Quicksort, or partition-exchange sort, is a sorting algorithm developed by Tony Hoare that, on average, makes O(n log n) comparisons to sort n items. In the worst case, it makes O(n2) comparisons, though this behavior is rare. Quicksort is often faster in practice than other O(n log n) algorithms. Additionally, quicksort's sequential and localized memory references work well with a cache. Quicksort is a comparison sort and, in efficient implementations, is not a stable sort. Quicksort can be implemented with an in-place partitioning algorithm, so the entire sort can be done with only O(log n) additional space used by the stack during the recursion.
Quicksort is a divide and conquer algorithm. Quicksort first divides a large array into two smaller sub-array: the low elements and the high elements. Quicksort can then recursively sort the sub-arrays.
The steps are:
- Pick an element, called a pivot, from the array.
- Reorder the array so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation.
- Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-array of elements with greater values.
Merge sort
In computer science, merge sort (also commonly spelled mergesort) is an O(n log n) comparison-based sorting algorithm. Most implementations produce a stable sort, which means that the implementation preserves the input order of equal elements in the sorted output. Mergesort is a divide and conquer algorithm that was invented by John von Neumann in 1945. A detailed description and analysis of bottom-up mergesort appeared in a report by Goldstine and Neumann as early as 1948.
Conceptually, a merge sort works as follows:
- Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element is considered sorted).
- Repeatedly merge sublists to produce new sorted sublists until there is only 1 sublist remaining. This will be the sorted list.
class Sort {
public:
Sort() {
int n = ;
srand(time(NULL));
n = rand() % + ;
for (int i = ; i < n; ++i) {
int v = rand() % ;
data.push_back(v);
data.push_back(v);
data.push_back(v);
data.push_back(v);
}
}
void bubbleSort() {
int n = data.size();
for (int i = ; i < n - ; ++i) {
bool swapped = false; // optimized
for (int j = ; j < n - i; ++j) {
if (data[j] >= data[j - ]) continue;
swap(data[j - ], data[j]);
swapped = true;
}
if (!swapped) return; // optimized
}
}
void insertSort() {
for (int i = ; i < data.size(); ++i) {
int tmp = data[i];
int j = i - ;
while (j >= && data[j] >= tmp) {
data[j + ] = data[j];
j--;
}
data[j + ] = tmp;
}
}
void selectSort() {
int n = data.size();
for (int i = ; i < n - ; ++i) {
int min = i;
for (int j = i + ; j < n; ++j) {
if (data[j] < data[min]) min = j;
}
if (min != i) {
swap(data[min], data[i]);
}
}
}
void heapSort() {
int n = data.size();
for (int i = n / - ; i >= ; --i) {
adjust(i, n - );
}
for (int i = ; i < n - ; ++i) {
swap(data[], data[n - i - ]);
adjust(, n - i - );
}
}
void quickSort() {
qSortHelper(, data.size() - );
}
void mergeSort() {
//mSortHelper(0, data.size() - 1);
mSortHelper2(, data.size() - );
}
void print() const {
for (int i = ; i < data.size(); ++i)
cout << data[i] << " ";
cout << endl;
}
bool isSorted() const {
for (int i = ; i < data.size(); ++i)
if (data[i] < data[i - ]) return false;
return true;
}
int operator[](int index) {
if (index < || index >= data.size()) return -;
else return data[index];
}
int size() const { return data.size(); }
private:
void swap(int& a, int& b) {
int t = a;
a = b;
b = t;
}
void adjust(int start, int end) {
if (start >= end) return;
int i = start;
int tmp = data[start];
while (i < end) { // this condition can be changed to i * 2 + 1 <= end
int left = i * + ;
if (left > end) break;
int right = i * + ;
int max = left;
if (right <= end && data[max] < data[right]) max = right;
if (tmp >= data[max]) break; // bug, must compare with data[start], not data[i]
data[i] = data[max];
i = max;
}
data[i] = tmp;
}
void qSortHelper(int start, int end) {
if (start >= end) return;
int i = start + , j = end;
while (i < j) {
while (j > start && data[j] >= data[start]) j--;
while (i <= end && data[i] <= data[start]) i++;
if (i >= j) break;
swap(data[i], data[j]);
}
if (data[j] <= data[start]) swap(data[j], data[start]); // when there are > 2 numbers left
qSortHelper(start, j - );
qSortHelper(j + , end);
}
// two consecutive ranges: [l1, r1] [l2, r2]
void mergeRange(int l1, int r1, int l2, int r2) {
vector<int> copy;
int i = l1, j = l2;
while (i <= r1 && j <= r2) {
if (data[i] < data[j]) {
copy.push_back(data[i]);
i++;
} else {
copy.push_back(data[j]);
j++;
}
}
while (i <= r1) {
copy.push_back(data[i]);
i++;
}
while (j <= r2) {
copy.push_back(data[j]);
j++;
}
for (int i = l1; i <= r2; ++i) { // bug here
data[i] = copy[i - l1];
}
}
// top down merge
void mSortHelper(int start, int end) {
if (end - start < ) return;
if (end - start == && data[start] > data[end]) {
swap(data[start], data[end]);
return;
}
int mid = (end + start) / ;
mSortHelper(start, mid);
mSortHelper(mid + , end);
mergeRange(start, mid, mid + , end); // reconstruct
}
// bottom up merge
void mSortHelper2(int start, int end) {
for (int width = ; width < data.size(); width <<= ) {
for (int i = ; i < data.size(); i += (width << )) {
int end = i + (width << ) - ;
if (end >= data.size()) end = data.size();
mergeRange(i, i + width - , i + width, end);
}
}
}
vector<int> data;
};
http://en.wikipedia.org/wiki/Sorting_algorithm
Algorithm | Sort的更多相关文章
- C++ 中的sort排序用法
STL中就自带了排序函数sortsort 对给定区间所有元素进行排序 要使用此函数只需用#include <algorithm> sort即可使用,语法描述为:sort(begin,end ...
- (转)qsort和sort
1.qsort函数: 原 型: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *)) ...
- sort()和qsort()方法详解
1,C++自带的自动排序方法:sort(); 要使用此函数只需用#include <algorithm> sort即可使用. sort(begin,end),表示一个范围,例如: int ...
- C++ 排序函数 sort(),qsort()的用法
转自:http://blog.csdn.net/zzzmmmkkk/article/details/4266888/ 所以自己总结了一下,首先看sort函数见下表: 函数名 功能描述 sort 对给定 ...
- 41.把数组排成最小的数[Sort array to smallest value]
[题目] 输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{3,32, 321},则输出这两个能排成的最小数字321323.请给出解决问题的算法,并证明该 ...
- 排序(sort qsort)
qsort() 函数: sort() 函数表: 函数名 功能描述 sort 对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 partial_sort 对给定区间所 ...
- (C++)STL排序函数sort和qsort的用法与区别
主要内容: 1.qsort的用法 2.sort的用法 3.qsort和sort的区别 qsort的用法: 原 型: void qsort(void *base, int nelem, int widt ...
- C++ 排序函数 sort(),qsort()的使用方法
想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~ 所以自己总结了一下,首先看sort函数见下表: 函数名 功能描写叙述 sort 对给 ...
- c++中sort()及qsort()的使用方法总结
当并算法具体解释请见点我 想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~ 所以自己总结了一下,首先看sort函数见下表: 函数名 ...
随机推荐
- Linux 用户行为日志记录
工作中我们常常遇到,有的员工不安于被分配的权限,老是想sudo echo "ziji" /usr/bin/visudo NOPASSWD:ALL来进行提权,造成误删了数据库某条重要 ...
- 访问tomcat出现HTTP Status 500 - java.lang.IllegalStateException: No output folder
问题:tomcat分为安装版和解压缩版,解压缩版如果解压到安装盘,在浏览器中访问http://localhost:8080,可能会出现500错误,错误提示如下: localhost:8080 jav ...
- 《鸟哥的Linux私房菜》学习笔记(6)——管道及IO重定向
一.标准I/O 标准输入:也可以叫STDIN,用0来标识,通常是键盘 标准输出:也 ...
- MySQL之索引(四)
压缩索引 MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能.默认只压缩字符串,但通过参数设置也可以对整数做压缩. MyISAM压缩每个索引块的方 ...
- pycharm许可证过期
1.选择enter license 2.选择license server 3.输入http://idea.imsxm.com 4.点击ok 好,解决了
- Mybatis使用- Mybatis JdbcType与Oracle、MySql数据类型对应列表 ; Mybatis中javaType和jdbcType对应关系
Mybatis JdbcType与Oracle.MySql数据类型对应列表 Mybatis JdbcType Oracle MySql JdbcType ARRAY JdbcType BIG ...
- Android TextWatcher的使用方法(监听ExitText的方法)
我做了一个查询单词的简单app, 当在EditText中输入单词的时候,点击lookup,则在TextView区域显示出该单词的意思,当EditText中没有任何字符时,显示"word de ...
- hnust 聚宝盆
问题 A: 聚宝盆 时间限制: 1 Sec 内存限制: 128 MB提交: 663 解决: 282[提交][状态][讨论版] 题目描述 Grace是个善良的同学,他经常帮助同学解决问题.这天,他正 ...
- Unity3D - 设计模式 - 工厂模式
工厂模式:以食物生产为例 1. 一个生产食物的工厂(此项 需要建立两个类:食物基类<Food>,工厂类<Factory>) 2. 可以生产不同的食物(此项 建立食物的具体子类, ...
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...