插入排序和归并排序 [Algorithm]

来源:互联网 发布:netbeans php插件推荐 编辑:程序博客网 时间:2024/04/30 04:33
插入排序:
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;//+1ptr_type former = new type[fsize];for (int i(0); i<fsize; i++)former[i] = ptr[bg+i];int lsize = end-mid;//end-mid-1 + 1ptr_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++];elseptr[aidx] = latter[lidx++];}else if (lidx < lsize)ptr[aidx] = latter[lidx++];elseptr[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 millionsrand((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;//+1ptr_type former = new type[fsize];for (int i(0); i<fsize; i++)former[i] = ptr[bg+i];int lsize = end-mid;//end-mid-1 + 1ptr_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++];elseptr[aidx] = latter[lidx++];}else if (lidx < lsize)ptr[aidx] = latter[lidx++];elseptr[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

 

 

0 0