排序算法
/*
* =====================================================================================
*
* Filename: sort.h
*
* Description: template func of rand & sort alg
*
* Version: 1.0
* Created: 2012年03月08日 15时36分00秒
* Revision: none
* Compiler: gcc
*
* Author: Lavey Luo (lavey), luoyi.smt@gmail.com
* Organization:
*
* =====================================================================================
*/
#ifndef __SORT_H__
#define __SORT_H__
namespace stcpp
{
template<class T>
/* Rand the n elements a[0..n-1] */
/* elements ranks returned in r[0..n-1] */
void Rank(T a[], int n, int r[])
{
for (int i = 0; i < n; i++)
r[i] = 0;
/* the flow loop has the same result */
#if 0
for (int i = 0; i < n; i++)
for (int j = i+1; j < n; j++)
if (a[i] > a[j])
r[i] += 1;
else
r[j] += 1;
#else
for (int i = 1; i < n; i++)
for (int j = 0; j < i; j++)
if (a[i] >= a[j])
r[i] += 1;
else
r[j] += 1;
#endif
}
/* 根据数组a的元素排序位置r,将其按大小重派 */
template<class T>
/* In-place rearrangement into sorted order */
void Rearrange(T a[], const int n, int r[])
{
T tmp[n];
// move the correct place in tmp
for (int i = 0; i < n; i++)
tmp[r[i]] = a[i];
// replace by the sorted array
for (int i = 0; i < n; i++)
a[i] = tmp[i];
}
/* 选择排序。从小到大排,每次选择剩下元素中最小的放到对应位置 */
template<class T>
void SelectionSort(T a[], int n)
{
for (int i = 0; i < n; i++)
{
// find the min
int k = i;
for (int j = i + 1; j < n; j++ )
{
if (a[k] > a[j])
k = j;
}
//swap a[i] with a[k]
if (k != i)
{
T b = a[i]; a[i] = a[k]; a[k] = b;
}
}
}
/* 冒泡排序,相邻的两两相比,大的放右边 */
template<class T>
void BubbleSort(T a[], int n)
{
for (int i = 0; i < n; i++)
for (int j = 1; j < n - i; j++ )
if (a[j-1] > a[j])
{
T b = a[j-1]; a[j-1] = a[j]; a[j] = b;
}
}
/* 冒泡排序,优化对已排好的序的跳过*/
template<class T>
void BubbleSort_q(T a[], int n)
{
bool sorted = false;
for (int i = 0; i < n && !sorted; i++)
{
sorted = false;
for (int j = n - 1; j > i; j-- )
{
if (a[j-1] > a[j])
{
T b = a[j-1]; a[j-1] = a[j]; a[j] = b;
sorted = true;
}
}
}
}
/* 插入排序 */
template<class T>
void InsertionSort(T a[], int n)
{
for (int i = 1; i < n; i++) /* 从位置1开始 */
{
T e = a[i]; /* 记住哨兵 */
Insert(a, i, e);
}
}
template<class T>
void Insert(T a[], int n, const T& e) /* 在有序的数组a[0, n-1]中插入元素e */
{
int i = n - 1;
for (; i >= 0 && a[i] > e; i--)
a[i+1] = a[i];
a[i+1] = e;
}
/* 插入排序2, 合并插入过程 */
template<class T>
void InsertionSort2(T a[], int n)
{
for (int i = 1; i < n; i++)
{
int j = i - 1;
T e = a[i]; /* 记住要插入的元素值,不能直接引用a[i] */
// 插入元素到合适的位置
for (; j >= 0 && a[j] > e; j--)
a[j+1] = a[j];
a[j+1] = e;
}
}
/* 希尔排序 */
template<class T>
void ShellSort(T a[], int n)
{
int i, j;
int increment = n;
do
{
increment = increment/3 +1;/* 增量序列 */
for ( i = increment; i < n; i++)
{
if (a[i] < a[i-increment])
{
T e = a[i];
j = i - increment;
do /* 查找e的插入位置*/
{
a[j+increment] = a[j]; /* 记录后移,查找插入位置 */
j = j - increment;
} while (j>0 && e < a[j]);
a[j+increment] = e; /* 插入 */
}
}
} while (increment>1);
}
/* 归并排序 */
template<class T>
/* 将有序的a[begin...mind] 和 a[mind+1...end] 归并为有序的b[begin...end]*/
void Merge(T a[], T b[], int begin, int mind , int end)
{
int begin1 = begin;
int end1 = mind;
int begin2 = mind+1;
int end2 = end;
int k = begin;
while (begin1 <= end1 && begin2 <= end2) /* 将a[]中的元素从小到大归并到b[] */
{
if (a[begin1] < a[begin2])
b[k++] = a[begin1++];
else
b[k++] = a[begin2++];
}
/* 将剩余的a[begin1...end1]复制到b[] */
if (begin1 <= end1)
{
while (begin1 <= end1)
b[k++] = a[begin1++];
}
/* 将剩余的a[begin2...end2]复制到b[] */
if (begin2 <= end2)
{
while (begin2 <= end2)
b[k++] = a[begin2++];
}
}
/* 递归归并排序 */
template<class T>
/* =将a[s..t]归并排序为b[s..t] */
void MSort(T a[], T b[], int s, int t)
{
int m = (s+t)/2;
T TMP[100]; //最大的临时空间
if (s == t)
b[s] = a[s];
else
{
MSort(a, TMP, s, m);
MSort(a, TMP, m+1, t);
Merge(TMP, b, s, m, t);
}
}
template<class T>
void MergSort1(T a[], int len)
{
MSort(a, a, 0, len -1);
}
/* 非递归归并排序 */
template<class T>
/* 将a[]中相邻长度为seg的字串两两归并到b[], a的长度为size */
void MergePass(T a[], T b[], int seg, int size)
{
int start_seg = 0;
while (start_seg < size - 2*seg) //满足两两归并的最少长度
{
Merge(a, b, start_seg, start_seg + seg -1, start_seg + 2*seg -1);
start_seg += 2*seg;
}
if (start_seg + seg < size) /* 还剩余大于seg长度的序列 */
{
Merge(a, b, start_seg, start_seg + seg -1, size -1);
}
else
{
while (start_seg < size)
{
b[start_seg] = a[start_seg];
start_seg++;
}
}
}
template<class T>
void MergeSort2(T a[], int len)
{
T* tmp = new T[len];
int seg = 1;
while (seg < len)
{
MergePass(a, tmp, seg, len);
seg *= 2;
MergePass(tmp, a, seg, len);
seg *= 2;
}
}
/* 堆排序 */
template<class T>
void HeapAdjust(T a[], int s, int m)
{
int temp = a[s];
for (int j = 2*s; j<=m; j*=2) // j 为s的子节点
{
if (j < m && a[j] < a[j+1])
++j; // 指向右子节点
if (temp >= a[j])
break;
a[s] = a[j];
s = j;
}
a[s] = temp; // 插入
}
template<class T>
void HeapSort(T a[], int len)
{
/* 构建一个大顶堆 */
for (int i = len/2 - 1; i>= 0; i--)
HeapAdjust(a, i, len);
for(int i = len -1; i>0; i--)
{
T t = a[0];
a[0] = a[i];
a[i] = t;
HeapAdjust(a, 0, i-1);
}
}
/* 快速排序 */
template<class T>
int Partition(T a[], int low, int high)
{
int pivotkey = a[low];
while (low < high)
{
while (low < high && a[high] >= pivotkey)
high--;
// swap a[low] with a[high]
T t = a[low];
a[low] = a[high];
a[high] = t;
while (low < high && a[low] <= pivotkey)
low++;
t = a[low];
a[low] = a[high];
a[high] = t;
}
return low;
}
template<class T>
void QSort(T a[], int low, int high)
{
int pivot;
if (low < high)
{
pivot = Partition(a, low, high);
QSort(a, low, pivot -1);
QSort(a, pivot + 1, high);
}
}
template<class T>
void QuickSort(T a[], int len)
{
QSort(a, 0, len -1);
}
}
#endif //__SORT_H__
测试用列:
/*
* =====================================================================================
*
* Filename: test_sort.cpp
*
* Description: test_sort
*
* Version: 1.0
* Created: 2012年03月08日 16时22分40秒
* Revision: none
* Compiler: gcc
*
* Author: Lavey Luo (lavey), luoyi.smt@gmail.com
* Organization:
*
* =====================================================================================
*/
#include "sort.h"
#include <iostream>
using std::cout;
using std::endl;
int test_sort(int argc, char** argv)
{
int a[] = {2, 6, 4, 3, 1, 5};
const unsigned int len = sizeof(a)/sizeof(int);
int r[len] = {0};
cout << "a: ";
for (unsigned int i = 0; i < len; i++)
cout << a[i] << " ";
cout << endl;
stcpp::Rank(a, len, r);
cout << "r: ";
for (unsigned int i = 0; i < len; i++)
cout << r[i] << " ";
cout << endl;
cout << endl << "Rearrange::" << endl;
stcpp::Rearrange(a, len, r);
cout << "sorted a: ";
for (unsigned int i = 0; i < len; i++)
cout << a[i] << " ";
cout << endl;
cout << endl << "SelectionSort::" << endl;
int b[] = {2, 6, 4, 3, 1, 5};
cout << "b: ";
for (unsigned int i = 0; i < sizeof(b)/sizeof(int); i++)
cout << b[i] << " ";
cout << endl;
stcpp::SelectionSort(b, sizeof(b)/sizeof(int));
cout << "sorted b: ";
for (unsigned int i = 0; i < sizeof(b)/sizeof(int); i++)
cout << b[i] << " ";
cout << endl;
cout << endl << "BubbleSort::" << endl;
int c[] = {2, 6, 4, 3, 1, 5};
cout << "c: ";
for (unsigned int i = 0; i < sizeof(c)/sizeof(int); i++)
cout << c[i] << " ";
cout << endl;
stcpp::BubbleSort(c, sizeof(c)/sizeof(int));
cout << "sorted c: ";
for (unsigned int i = 0; i < sizeof(c)/sizeof(int); i++)
cout << c[i] << " ";
cout << endl;
cout << endl << "InsertSort::" << endl;
int d[] = {2, 6, 4, 3, 1, 5};
cout << "d: ";
for (unsigned int i = 0; i < sizeof(d)/sizeof(int); i++)
cout << d[i] << " ";
cout << endl;
stcpp::InsertionSort(d, sizeof(d)/sizeof(int));
cout << "sorted d: ";
for (unsigned int i = 0; i < sizeof(d)/sizeof(int); i++)
cout << d[i] << " ";
cout << endl;
cout << endl << "InsertSort2::" << endl;
int e[] = {2, 6, 4, 3, 1, 5};
cout << "e: ";
for (unsigned int i = 0; i < sizeof(e)/sizeof(int); i++)
cout << e[i] << " ";
cout << endl;
stcpp::InsertionSort2(e, sizeof(e)/sizeof(int));
cout << "sorted e: ";
for (unsigned int i = 0; i < sizeof(e)/sizeof(int); i++)
cout << e[i] << " ";
cout << endl;
cout << endl << "Shell sort::" << endl;
int f[] = {2, 6, 4, 3, 1, 5};
cout << "f: ";
for (unsigned int i = 0; i < sizeof(f)/sizeof(int); i++)
cout << f[i] << " ";
cout << endl;
stcpp::ShellSort(f, sizeof(f)/sizeof(int));
cout << "sorted f: ";
for (unsigned int i = 0; i < sizeof(f)/sizeof(int); i++)
cout << f[i] << " ";
cout << endl;
cout << endl << "merge sort 1::" << endl;
int g[] = {2, 6, 4, 3, 1, 5};
cout << "g: ";
for (unsigned int i = 0; i < sizeof(g)/sizeof(int); i++)
cout << g[i] << " ";
cout << endl;
stcpp::MergSort1(g, sizeof(g)/sizeof(int));
cout << "sorted g: ";
for (unsigned int i = 0; i < sizeof(g)/sizeof(int); i++)
cout << g[i] << " ";
cout << endl;
cout << endl << "merge sort 2::" << endl;
int h[] = {2, 6, 4, 3, 1, 5};
cout << "h: ";
for (unsigned int i = 0; i < sizeof(h)/sizeof(int); i++)
cout << h[i] << " ";
cout << endl;
stcpp::MergeSort2(h, sizeof(h)/sizeof(int));
cout << "sorted h: ";
for (unsigned int i = 0; i < sizeof(h)/sizeof(int); i++)
cout << h[i] << " ";
cout << endl;
cout << endl << "heap sort 2::" << endl;
int hh[] = {2, 6, 4, 3, 1, 5};
cout << "hh: ";
for (unsigned int i = 0; i < sizeof(hh)/sizeof(int); i++)
cout << hh[i] << " ";
cout << endl;
stcpp::HeapSort(hh, sizeof(hh)/sizeof(int));
cout << "sorted hh: ";
for (unsigned int i = 0; i < sizeof(hh)/sizeof(int); i++)
cout << hh[i] << " ";
cout << endl;
cout << endl << "quick sort 2::" << endl;
int qq[] = {2, 6, 4, 3, 1, 5};
cout << "qq: ";
for (unsigned int i = 0; i < sizeof(qq)/sizeof(int); i++)
cout << qq[i] << " ";
cout << endl;
stcpp::QuickSort(qq, sizeof(qq)/sizeof(int));
cout << "sorted qq: ";
for (unsigned int i = 0; i < sizeof(qq)/sizeof(int); i++)
cout << qq[i] << " ";
cout << endl;
return 0;
}