插入排序:
template<typename T>
void insert_sort(T* ptr, int length)
{
typedef T type;
typedef type* ptr_type;
type key;
for (int i(1); i<length; i++)
{
key = ptr[i];
int j = i-1;
while (j>=0 && ptr[j]>key)
{
ptr[j+1] = ptr[j];
j--;
}
ptr[j+1] = key;
}
}
归并排序:
//
// Test Case: merge(ptr, i, i, i+1);
// Test Case: merge(ptr, i, i, i);
//
template<typename T>
void merge(T *ptr, int bg, int mid, int end)
{
typedef T type;
typedef type* ptr_type;
//! [使用哨兵位]
//type imax = std::numeric_limits<type>::max();
//int fsize = mid-bg+1; //+1
//ptr_type former = new type[fsize+1];
//for (int i(0); i<fsize; i++)
// former[i] = ptr[bg+i];
//former[fsize] = imax;
//
//int lsize = end-mid; //end-mid-1 + 1
//ptr_type latter = new type[lsize+1];
//for (int i(0); i<lsize; i++)
// latter[i] = ptr[mid+1+i];
//latter[lsize] = imax;
//int fidx(0);
//int lidx(0);
//int aidx(bg);
//while (aidx<=end)
//{
// if (former[fidx] < latter[lidx])
// ptr[aidx] = former[fidx++];
// else
// ptr[aidx] = latter[lidx++];
// aidx++;
//}
//! [使用哨兵位]
//! [不使用哨兵位]
int fsize = mid-bg+1; //+1
ptr_type former = new type[fsize];
for (int i(0); i<fsize; i++)
former[i] = ptr[bg+i];
int lsize = end-mid; //end-mid-1 + 1
ptr_type latter = new type[lsize];
for (int i(0); i<lsize; i++)
latter[i] = ptr[mid+1+i];
int fidx(0);
int lidx(0);
int aidx(bg);
while (aidx<=end)
{
if (fidx < fsize && lidx < lsize)
{
if (former[fidx] < latter[lidx])
ptr[aidx] = former[fidx++];
else
ptr[aidx] = latter[lidx++];
}
else if (lidx < lsize)
ptr[aidx] = latter[lidx++];
else
ptr[aidx] = former[fidx++];
aidx++;
}
//! [不使用哨兵位]
delete [] former; former = 0;
delete [] latter; latter = 0;
}
template<typename T>
void merge_sort(T* ptr, int bg, int end)
{
if (bg >= end)
return;
int mid = (bg+end)/2;
merge_sort(ptr, bg, mid);
merge_sort(ptr, mid+1, end);
merge(ptr, bg, mid, end);
}
插入排序时间复杂度是n^2, 空间复杂度为1
归并排序复杂度为nlgn, 空间复杂度为 n
在n较小的时候,插入排序较快, 当n较大的时候,归并排序优势异常明显,测试:
程序:
void test_insert_sort()
{
const int test_num = 100000; // 1 million
srand((int)time(0));
cout << "Test number " << "/t:/t/t" << test_num << std::endl;
int* testPtr = new int[test_num];
int* testPtr1 = new int[test_num];
for(int idx=0; idx<test_num; idx++)
testPtr1[idx] = testPtr[idx] = rand();
clock_t t = clock();
insert_sort(testPtr, test_num);
cout << "Insert Sort " << "/t:/t/t" << clock() - t << std::endl;
//for(int idx=0; idx<test_num; idx++)
// cout << testPtr[idx] << " ";
//cout << endl;
t = clock();
merge_sort(testPtr1, 0, test_num-1);
cout << "Merge Sort " << "/t:/t/t" << clock() - t << std::endl;
//for(int idx=0; idx<test_num; idx++)
// cout << testPtr1[idx] << " ";
//cout << endl;
// Test the result validity
for(int idx=0; idx<test_num; idx++)
assert(testPtr[idx]==testPtr1[idx]);
delete[] testPtr; testPtr = 0;
delete[] testPtr1; testPtr1 = 0;
}
结果:
// Test number : 1000
// Insert Sort : 1
// Merge Sort : 4
// Test number : 10000
// Insert Sort : 109
// Merge Sort : 27
// Test number : 100000
// Insert Sort : 11212
// Merge Sort : 363
附录:
归并排序的变种,
逆序对,A[1, n] 数组中,如果i<j, A[i] > A[j]. 则 (i, j)为A中一个逆序对(inversion).
用nlgn最坏情况下,求n个元素任意排列中的逆序对数目:
//
// 用nlog(n)最坏时间,确定n个元素任意排列的逆序对数目
//
template<typename T>
int gather_compute(T *ptr, int bg, int mid, int end)
{
typedef T type;
typedef type* ptr_type;
int ret_count = 0;
int fsize = mid-bg+1; //+1
ptr_type former = new type[fsize];
for (int i(0); i<fsize; i++)
former[i] = ptr[bg+i];
int lsize = end-mid; //end-mid-1 + 1
ptr_type latter = new type[lsize];
for (int i(0); i<lsize; i++)
latter[i] = ptr[mid+1+i];
int fidx(0);
int lidx(0);
int aidx(bg);
for (int i(0); i<fsize; i++)
for (int k=0; k<lsize; k++)
if (former[i]>latter[k])
ret_count++;
while (aidx<=end)
{
if (fidx < fsize && lidx < lsize)
{
if (former[fidx] < latter[lidx])
ptr[aidx] = former[fidx++];
else
ptr[aidx] = latter[lidx++];
}
else if (lidx < lsize)
ptr[aidx] = latter[lidx++];
else
ptr[aidx] = former[fidx++];
aidx++;
}
delete [] former; former = 0;
delete [] latter; latter = 0;
return ret_count;
}
template<typename T>
int compute_reverse_pair(T* ptr, int bg, int end)
{
if (bg >= end)
return 0;
int mid = (bg+end)/2;
return compute_reverse_pair(ptr, bg, mid) +
compute_reverse_pair(ptr, mid+1, end) +
gather_compute(ptr, bg, mid, end);
}
测试:
{
int test_data[] = {5,2,4,7,1,3,6};
int length = sizeof(test_data) / sizeof(test_data[0]);
cout << compute_reverse_pair(test_data, 0, length-1) << endl;
}
http://blog.csdn.net/ryfdizuo/article/details/6057479