#include <iostream>
using namespace std;
//划分函数:将数组划分为大于和小于某元素的两部分
template <typename T>
int partition_job(T *array, int left, int right)
{
int index = left;
int pivot = array[index];
swap(array[index],array[right]);
for(int i = left; i< right; i++)
{
if(array[i] > pivot)
{
swap(array[index++], array[i]);
}//降序
}
swap(array[right], array[index]);
return index;
}
//快速排序:分治法+挖空填空
//快速排序的平均时间复杂度为:O(nlog(n)),每次划分数组整体比较n次,分成两半。
template <typename T>
void qsort_job(T *array, int left, int right)
{
if(left >= right)
return ;
int index = partition_job(array, left, right);
qsort_job(array, left, index - 1);//做部分
qsort_job(array, index + 1, right);
}
//插入排序
//平均时间复杂度:O(n2);最好O(n):已排好序;最差O(n2):完全逆序。
/*
原理:
初始:首个元素自成一个有序(已排)序列,其余的记录为无序(待排)序列。
循环:从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中。
终止:直至最后一个记录插入到有序序列中为止。
*/
template <typename T>
void insertsort_job(T *data, int size)
{
for(int i = 1; i < size; i++)
{
T key = data[i];
int j(i-1);
for(; j >= 0 && data[j] > key; j--) //降序
data[j+1] = data[j];
data[j+1] = key;
}
}
//希尔排序:有间隔的插入排序,间隔逐渐减小,最后间隔为1
//不稳定的,
template <typename T>
void shellsort_job(T *data, size_t size)
{
for(int gap = size/2; gap > 0; gap /= 2)
{
for(int i = gap; i < size; ++i)
{
T key = data[i];
int j = 0;
for(j = i - gap; j >= 0 && data[j] > key; j -= gap) //降序
data[j+gap] = data[j];
data[j+gap] = key;
}
}
}
//归并排序
//时间复杂度:O(nlog(n)),取n次堆顶元素,并维护n次堆,每次维护时间为O(log(n))
/*
初始化:将整个序列建立成一个堆。
循环:堆顶元素(最值)与最后一个元素互换,堆的最后一个元素即为最大(以大顶堆为例)记录,完成一次排序
接着将前N-1个元素(即不包括最大记录)进行大顶堆维护,再将堆顶元素与最后一个元素互换,得到次大值。
重复以上步骤,直至堆中只剩一个记录,排序结束。
*/
template <typename T>
void Merge(T *array, int low, int mid, int high)
{
int i, j, k;
T *temp = (T *)malloc((high - low + 1) * sizeof(T));
i = low, j = mid + 1, k = 0;
while(i <= mid && j <= high) //合并已排好序的前后两半数组元素,以mid为中点分割。
{
if(array[i] < array[j]) //升序
temp[k++] = array[i++];
else
temp[k++] = array[j++];
}
while(i <= mid) //若前一半中还有未处理完的元素
temp[k++] = array[i++];
while(j <= high) //若后一半中还有未处理完的元素
temp[k++] = array[j++];
for(i = low, j = 0; i <= high; ++i) //将排好序的元素从临时数组temp输入到array中,并释放temp;
array[i] = temp[j++];
free(temp);
}
template <typename T>
void Mergesort(T *array, int low, int high)
{
int mid;
if(low < high)
{
mid = (low + high) >> 1;
//递归:二分分解,直至单元素
Mergesort(array, low, mid);
Mergesort(array, mid + 1, high);
//合并:每次合并都是合并两个排好序的子数组
Merge(array, low, mid, high);
}
}
//堆排序
//对堆进行调整,使下标从s到m的无序序列成为一个大顶堆
//堆的维护/保持
//一次堆维护的时间复杂度为O(lg(n))
template <typename T>
void HeapAjust(T *array, int s, int m)
{
int j, temp = array[s];
//节点s的左子树的下标为:2s+1,右子树下标:2s+2.其实下标为0;
for(j = 2*s; j <= m; j *=2)
{
//选出左右孩子中较大者与父节点比较
if(j < m && array[j] < array[j+1])
++j;
if(temp >= array[j]) //若父节点大于等于左右孩子,则满足大顶堆的定义,跳出循环
break;
array[s] = array[j]; //否则用较大的节点替换父节点
s = j; //记录下替换父节点的节点下标
}
array[s] = temp;
}
//堆的排序(排序过程不断的维护堆)
//http://blog.youkuaiyun.com/sdlwlxf/article/details/24645557
template <typename T>
void Heapsort(T *array, int len)
{
int i;
// 建堆,堆的叶子节点下标为len/2~len-1,
//初始化:第一轮循环之前:初始化时只有叶子节点,也是最大堆的根。
//保持:每次添加一个新节点都对堆进行维护保持。维护时间为O(lg(n))
//终止:当i=0时,每个都是最大堆的跟。一个堆建立了。
//建堆的时间复杂度为O(n)而不是O(nlg(n)),详见算法导论 P78.
for(i = len / 2 - 1; i >= 0; --i)
HeapAjust(array, i, len - 1);
//每次将堆顶的元素(数组中最大的元素)与最后元素互换,最大元素就排在最后了。
//由于换过来的元素不一定满足大顶堆,需要维护一次大顶堆,再转到步骤一,直至循环结束。
//排序结束,升序。
for(i = len - 1; i > 0; --i)
{
swap(array[0], array[i]);
HeapAjust(array, 0, i-1);
}
}
//直接选择排序
//时间复杂度为O(n2),与序列的初始状态无关。
//不稳定:例子:2 2 1
/*
简单选择排序的基本思想:第i趟简单选择排序是指通过n-i次关键字的比较,
从n-i+1个记录中选出关键字最小的记录,并和第i个记录进行交换。共需进行i-1趟比较,直到所有记录排序完成为止。
例如:进行第i趟选择时,从当前候选记录中选出关键字最小的k号记录,并和第i个记录进行交换。
*/
template <typename T>
void SelectSort(T *array, int len)
{
int i = 0, j = 0, k = 0;
for(i = 0; i < len - 1; ++i)
{
k = i;
for(j = i+1; j < len; ++j) //从后面选择一个最小的元素
{
if(array[j] < array[k])
k = j;
}
if(k != i) //与第i个元素交换
swap(array[i], array[k]);
}
}
//冒泡排序,下面这并不是真正的冒泡。
template <typename T>
void BubbleSort(T *array, int len)
{
int i = 0, j = 0;
for(i = 0; i < len - 1; ++i)
{
for(j = i + 1; j < len; ++j)
{
if(array[j] < array[i])
swap(array[i], array[j]);
}
}
}
template <typename T>
void BubbleSort2(T *array, int len)
{
int i = 0, j = 0;
for(i = 0; i < len - 1; ++i)
{
for(j = len - 1; j > i; --j)
{
if(array[j] < array[j-1]) //将最小值像水中气泡冒上去。
swap(array[j], array[j-1]);
}
}
}
int main()
{
int num;
int arr[200];
int count=0;
#if 0
while(cin>>num)
{
arr[count++]=num;
}
qsort_job(arr, 0, count-1);
for(int i = 0; i < count; i++)
{
cout << arr[i] << " ";
}
cout << endl;
#endif
while(cin>>num)
{
arr[count++]=num;
}
SelectSort(arr,count);
for(int i = 0; i < count; i++)
{
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
/*
参考
http://blog.youkuaiyun.com/hackbuteer1/article/details/6568913
*/