标签:
各种排序算法想必大家都不陌生,定义我就不多介绍了,直接写下自己的一些小结。
快速排序:可以算的上应用最广的排序算法。其排序思路是随机选取一个数字作为标志,使得小于它的数在它左边,大于它的数在它的右边,然后递归对两边的数据排序。
归并排序:应用分之的思想,先将要排序的分为两列,然后分别进行排序,然后合并到另一
个数组中,最后再进行把它复制回来。
冒泡排序:是稳定排序,适用于排列的数组较小而且基本有序,否则时间复杂度太高。
选择排序:和冒泡排序差不多,差别是冒泡是相邻的比较,最后选出最大的或者最小的,选
择排序是选一个点,然后把遍历把最小的和这个替换,两个思想差不多,但选择排序是不稳定排序,选择排序理论和实际上是比冒泡要快的。
插入排序:对于部分有序的数组这种算法很有用,因为有可能达到O(n)复杂度,但是一般的
话还是O(n*n)。
希尔排序:插入排序的变种,我们知道,插入排序它对数组无序太慢了,而且每次交换移动
一次太慢了,于是设计希尔排序,它每次移动的步长(h)是可变的,一般有一个那样的数组,可以存步 长,然后先h有序,再h/3有序,再h/3/3有序,最后1有序,此处的h/3只是一个设计,也可以用其它的。希尔排序很快,在数据量很大的情况下,比快速排序也就慢一倍,但是它不需要额外的空间。
堆排序: 对于从很多数据中选择几个最大的,不用完全排序就可以选出来,而且消耗的时
间和空间有个折衷。例如说从10亿个数据中选10个最大的,只需维护一个10大小的堆,然后每次添加数据将大于10的用堆删除就行了,消耗的时间复杂度为 O(n*logM),M为个数大小,此处为10,空间复杂度为M.
基数排序:有两种,一种从低位到高位,另一种从高位到低位,先按一位的大小排在一个桶
里,然后在排后面的位。
废话不多说,直接上代码。
// sort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <algorithm>
using namespace std;
//冒泡排序
void BubbleSort(int *arr, int length)
{
cout << "bubble sort:" << endl;
if (arr==NULL||length <= 0)
return;
for (int i = length - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (arr[j]>arr[j + 1])
swap(arr[j], arr[j + 1]);
}
//选择排序
void SelectSort(int *arr, int length)
{
cout << "select sort: " << endl;
if (length <= 0)
return;
for (int i = 0; i < length - 1;i++)
for (int j = i; j < length - 1; j++)
{
if (arr[j] < arr[i])
swap(arr[i], arr[j]);
}
}
//网上看的选择排序的实现,比自己没有那么多次交换,人是每次都记录最小的所在的位置,每次都更新位置,最后找到一个最小的再交换,比我的优化多了
template <class T>
void selection_sort(T a[], int n)
{ // 不稳定; 反例: { 2, 2, 1 }
int min;
for (int i = 0; i < n - 1; ++i) { // 最多做n-1趟排序
min = i; // 先假设a[i]最小
for (int j = i + 1; j < n; ++j) // 在当前无序区a[i:n-1]中查找最小值
if (a[j] < a[min])
min = j; // min记下当前无序区最小值所在位置
if (min != i) // 找到比当前a[i]更小者
std::swap(a[i], a[min]);
}
}
//插入排序
void InsertSort(int *arr, int length)
{
cout << "insert sort: " << endl;
if (arr == NULL || length < 0)
return;
for (int i = 1; i < length; i++)
{
for (int j = i; j > 0; j--)
{
if (arr[j]<arr[j - 1])
swap(arr[j], arr[j - 1]);
else
break;
}
}
return;
}
//希尔排序,其实就是插入排序的变种,但是比插入排序快多了
void ShellSort(int *arr, int length)
{
cout << "shell sort: " << endl;
int h = 1;
while (h < length / 3) h = 3 * h + 1; //1,4,13,40,121,364,1093...其实这个数组是科学家设计出来的,我们只需用就行了,一般程序中可以直接用一个数组将这些值放入
while (h >= 1)
{
for (int i = h; i < length; i++)
{
for (int j = i; j >= h&&arr[j] < arr[j - h]; j -= h)
swap(arr[j], arr[j - h]);
}
h = h / 3;//先h有序,再h/3有序,再h/3/3有序,最后1有序
}
}
//堆排序
void sink(int *arr, int start, int end);
void HeapSort(int *arr, int length)
{
cout << "heap sort: " << endl;
for (int k = length / 2; k >= 0; k--)
sink(arr, k, length-1);
length--;
while (length > 0)
{
swap(arr[0], arr[length--]);
sink(arr, 0, length);
}
}
void sink(int *arr, int start, int end)
{
while (2*start+1<=end)
{
int j = 2 * start + 1;
if (j<end&&arr[j]<arr[j + 1]) j++; //此处调了两个小时,,,,注意如果首先是选最大值,先试着选出两个儿子中的最大值,再和他们的最大值交换,开始没想到。。。。
if (arr[start] > arr[j])
break;
swap(arr[start], arr[j]);
start = j;
}
}
//基数排序
int bit(int *arr, int length);
void RadixSort(int *arr, int length)
{
cout << "radix sort: " << endl;
int d = bit(arr, length);
int *tmp = new int[length];
int *count = new int[10];
int i,k,begin=1;
while (d > 0)
{
for (i = 0; i < 10; i++)
count[i] = 0;
for (i = 0; i < length; i++)
{
k = (arr[i] / begin) % 10;
count[k]++;
}
for (i = 1; i < 10; i++)
{
count[i] = count[i - 1] + count[i];
}
for (i = 0; i < length; i++)
{
k = (arr[i] / begin) % 10;
tmp[count[k]-1] = arr[i];
count[k]--;
}
for (i = 0; i < length; i++)
arr[i] = tmp[i];
begin *= 10;
d--;
}
delete[] tmp;
delete[] count;
}
int bit(int *arr, int length)
{
int d = 1,k=10;
for (int i = 0; i < length; i++)
{
while (arr[i]>=k)
{
d++;
k *= 10;
}
}
return d;
}
//归并排序
void MergeSort(int *arr,int left, int right);
void Merge(int* arr, int left, int mid, int right);
void MergeSort(int *arr, int length)
{
cout << "merge sort: " << endl;
if (arr == NULL || length < 0)
return;
MergeSort(arr, 0, length - 1);
}
void MergeSort(int *arr, int left, int right)
{
/* if (left >= right)
return;
if (right - left == 1)
{
if (arr[right] < arr[left])
swap(arr[left], arr[right]);
return;
}*/
if (left < right)
{
int mid = left + (right - left) / 2;
MergeSort(arr, left, mid);
MergeSort(arr, mid + 1, right);
Merge(arr, left, mid, right);
}
}
void Merge(int* arr, int left, int mid, int right)
{
int *temp = new int[right + 1]; //不能直接定义一个静态数组,因为编译的时候没传具体数组大小不好分配空间,故此处用动态数组,开始这里错了,折腾好久
for (int i = left; i <= right; i++)
{
temp[i] = arr[i];
}
int i = left, j = mid + 1,index=left;
/* for (int k = left; k <= right; k++)
{
if (i > mid) arr[k] = temp[j ++];
else if (j > right) arr[k] = temp[i++];
else if (temp[i] < temp[j]) arr[k] = temp[i++];
else
arr[k] = temp[j++];
}*/
while (index <= right)
{
if (i>mid)
arr[index++] = temp[j++];
else if (j > right)
arr[index++] = temp[i++];
else if (temp[i] > temp[j])
arr[index++] = temp[j++];
else
arr[index++] = temp[i++];
}
delete [] temp;
}
//快速排序
void QuickSort(int *arr, int length, int left, int right);
int partion(int *arr,int length, int left, int right);
void QuickSort(int *arr, int length)
{
cout << "quick sort: " << endl;
QuickSort(arr,length, 0, length - 1);
}
void QuickSort(int *arr,int length, int left, int right)
{
if (right <= left)
return;
int i = partion(arr,length, left, right);
if (i > 0)
QuickSort(arr, length,left, i - 1);
if (i < right)
QuickSort(arr, length,i + 1, right);
}
int partion(int *arr, int length, int left, int right)
{
if (arr == NULL || length <= 0 || left < 0 || right >= length)
return -1;
srand(time(NULL));
int i = (rand() % (right+1-left))+left;
swap(arr[i], arr[right]);
int start = left - 1;
int index = left;
for (index = left; index <= right; index++)
{
if (arr[index] < arr[right])
{
start++;
if (start != index)
swap(arr[start], arr[index]);
}
}
start++;
swap(arr[start], arr[right]);
return start;
}
void print(int *arr, int length)
{
for (int i = 0; i < length; i++)
cout << arr[i] << " ";
cout << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int array[10] = { 3, 4, 6, 1, 2, 7, 8, 9, 5, 0 };
// BubbleSort(array, 10);
// MergeSort(array, 10);
// QuickSort(array, 10);
// InsertSort(array, 10);
// ShellSort(array, 10);
// HeapSort(array, 10);
RadixSort(array, 10);
print(array, 10);
return 0;
}
自己从几个方面对各个排序算法性能做一个比较,因为第一次写博客,不会画表格,只好截个图拿上来了。。。
总结:对于较大的数组,且不要求稳定的排序,可以考虑用快速排序;
而对于要求稳定的排序,则考虑归并排序;
对于较小的数组,且有序,可以考虑选择排序和插入排序;
堆排序对于从众多数据中选择几个优的在时间和空间上有个折衷。
标签:
原文地址:http://blog.csdn.net/hyp1977/article/details/51364396