插入排序和歸併排序 [Algorithm]

來源:互聯網
上載者:User

插入排序:

template<typename T><br />void insert_sort(T* ptr, int length)<br />{<br />typedef T type;<br />typedef type* ptr_type;</p><p>type key;</p><p>for (int i(1); i<length; i++)<br />{<br />key = ptr[i];</p><p>int j = i-1;<br />while (j>=0 && ptr[j]>key)<br />{<br />ptr[j+1] = ptr[j];<br />j--;<br />}</p><p>ptr[j+1] = key;<br />}<br />}

 

歸併排序:

//////////////////////////////////////////////////////////////////////////<br />//Test Case: merge(ptr, i, i, i+1);<br />//Test Case: merge(ptr, i, i, i);<br />//////////////////////////////////////////////////////////////////////////<br />template<typename T><br />void merge(T *ptr, int bg, int mid, int end)<br />{<br />typedef T type;<br />typedef type* ptr_type;</p><p>//![使用哨兵位]<br />//type imax = std::numeric_limits<type>::max();<br />//int fsize = mid-bg+1;//+1<br />//ptr_type former = new type[fsize+1];<br />//for (int i(0); i<fsize; i++)<br />//former[i] = ptr[bg+i];<br />//former[fsize] = imax;<br />//<br />//int lsize = end-mid;//end-mid-1 + 1<br />//ptr_type latter = new type[lsize+1];<br />//for (int i(0); i<lsize; i++)<br />//latter[i] = ptr[mid+1+i];<br />//latter[lsize] = imax;</p><p>//int fidx(0);<br />//int lidx(0);<br />//int aidx(bg);<br />//while (aidx<=end)<br />//{<br />//if (former[fidx] < latter[lidx])<br />//ptr[aidx] = former[fidx++];<br />//else<br />//ptr[aidx] = latter[lidx++];<br />//aidx++;<br />//}<br />//![使用哨兵位]</p><p>//![不使用哨兵位]<br />int fsize = mid-bg+1;//+1<br />ptr_type former = new type[fsize];<br />for (int i(0); i<fsize; i++)<br />former[i] = ptr[bg+i];</p><p>int lsize = end-mid;//end-mid-1 + 1<br />ptr_type latter = new type[lsize];<br />for (int i(0); i<lsize; i++)<br />latter[i] = ptr[mid+1+i];</p><p>int fidx(0);<br />int lidx(0);<br />int aidx(bg);<br />while (aidx<=end)<br />{<br />if (fidx < fsize && lidx < lsize)<br />{<br />if (former[fidx] < latter[lidx])<br />ptr[aidx] = former[fidx++];<br />else<br />ptr[aidx] = latter[lidx++];<br />}<br />else if (lidx < lsize)<br />ptr[aidx] = latter[lidx++];<br />else<br />ptr[aidx] = former[fidx++];</p><p>aidx++;<br />}<br />//![不使用哨兵位]</p><p>delete [] former; former = 0;<br />delete [] latter; latter = 0;<br />}</p><p>template<typename T><br />void merge_sort(T* ptr, int bg, int end)<br />{<br />if (bg >= end)<br />return;</p><p>int mid = (bg+end)/2;</p><p>merge_sort(ptr, bg, mid);<br />merge_sort(ptr, mid+1, end);<br />merge(ptr, bg, mid, end);<br />}

 

插入排序時間複雜度是n^2, 空間複雜度為1

 歸併排序複雜度為nlgn,  空間複雜度為 n

在n較小的時候,插入排序較快, 當n較大的時候,歸併排序優勢異常明顯,測試:

程式:

{<br />const int test_num = 100000;// 1 million<br />srand((int)time(0));</p><p>cout << "Test number " << "/t:/t/t" << test_num << std::endl;</p><p>int* testPtr = new int[test_num];<br />int* testPtr1 = new int[test_num];</p><p>for(int idx=0; idx<test_num; idx++)<br />testPtr1[idx] = testPtr[idx] = rand();</p><p>clock_t t = clock();<br />insert_sort(testPtr, test_num);<br />cout << "Insert Sort " << "/t:/t/t" << clock() - t << std::endl;</p><p>//for(int idx=0; idx<test_num; idx++)<br />//cout << testPtr[idx] << " ";<br />//cout << endl;</p><p>t = clock();<br />merge_sort(testPtr1, 0, test_num-1);<br />cout << "Merge Sort " << "/t:/t/t" << clock() - t << std::endl;</p><p>//for(int idx=0; idx<test_num; idx++)<br />//cout << testPtr1[idx] << " ";<br />//cout << endl;</p><p>// Test the result validity<br />for(int idx=0; idx<test_num; idx++)<br />assert(testPtr[idx]==testPtr1[idx]);</p><p>delete[] testPtr;testPtr = 0;<br />delete[] testPtr1;testPtr1 = 0;<br />}

 

結果:

// Test number : 1000<br />// Insert Sort : 1<br />// Merge Sort : 4</p><p>// Test number : 10000<br />// Insert Sort : 109<br />// Merge Sort : 27</p><p>// Test number : 100000<br />// Insert Sort : 11212<br />// Merge Sort : 363

 

附錄:

歸併排序的變種,

逆序對,A[1, n] 數組中,如果i<j, A[i] > A[j]. 則 (i, j)為A中一個逆序對(inversion).

用nlgn最壞情況下,求n個元素任意排列中的逆序對數目:

//////////////////////////////////////////////////////////////////////////<br />//用nlog(n)最壞時間,確定n個元素任意排列的逆序對數目<br />//////////////////////////////////////////////////////////////////////////<br />template<typename T><br />int gather_compute(T *ptr, int bg, int mid, int end)<br />{<br />typedef T type;<br />typedef type* ptr_type;</p><p>int ret_count = 0;</p><p>int fsize = mid-bg+1;//+1<br />ptr_type former = new type[fsize];<br />for (int i(0); i<fsize; i++)<br />former[i] = ptr[bg+i];</p><p>int lsize = end-mid;//end-mid-1 + 1<br />ptr_type latter = new type[lsize];<br />for (int i(0); i<lsize; i++)<br />latter[i] = ptr[mid+1+i];</p><p>int fidx(0);<br />int lidx(0);<br />int aidx(bg);</p><p>for (int i(0); i<fsize; i++)<br />for (int k=0; k<lsize; k++)<br />if (former[i]>latter[k])<br />ret_count++;</p><p>while (aidx<=end)<br />{<br />if (fidx < fsize && lidx < lsize)<br />{<br />if (former[fidx] < latter[lidx])<br />ptr[aidx] = former[fidx++];<br />else<br />ptr[aidx] = latter[lidx++];<br />}<br />else if (lidx < lsize)<br />ptr[aidx] = latter[lidx++];<br />else<br />ptr[aidx] = former[fidx++];</p><p>aidx++;<br />}</p><p>delete [] former; former = 0;<br />delete [] latter; latter = 0;</p><p>return ret_count;<br />}</p><p>template<typename T><br />int compute_reverse_pair(T* ptr, int bg, int end)<br />{<br />if (bg >= end)<br />return 0;</p><p>int mid = (bg+end)/2;</p><p>return compute_reverse_pair(ptr, bg, mid) +<br />compute_reverse_pair(ptr, mid+1, end) +<br /> gather_compute(ptr, bg, mid, end);<br />}<br />

測試:

{<br />int test_data[] = {5,2,4,7,1,3,6};<br />int length = sizeof(test_data) / sizeof(test_data[0]);</p><p>cout << compute_reverse_pair(test_data, 0, length-1) << endl;<br />}<br />

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.