• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天之道

            享受編程的樂趣。
            posts - 118, comments - 7, trackbacks - 0, articles - 0
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            歸并排序法是將兩個(gè)(或兩個(gè)以上)有序表合并成一個(gè)新的有序表,即把待排序序列分為若干個(gè)子序列,每個(gè)子序列是有序的。然后再把有序子序列合并為整體有序序列。
            例如,有數(shù)列{6,202,100,301,38,8,1}
            1.  剛開始的分組如下:
              i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 比較次數(shù)為3次
             2. 第二次,兩兩分組合并
              i=2 [ 6 100 202 301 ] [ 1 8 38 ] 比較次數(shù)為4
            3.  第三次,繼續(xù)合并
              i=3 [ 1 6 8 38 100 202 301 ] 比較次數(shù)為4
            總計(jì)的比較次數(shù)為11次
            歸并排序具體工作原理如下(假設(shè)序列共有n個(gè)元素):
            1.     將序列每相鄰兩個(gè)數(shù)字進(jìn)行歸并操作,形成floor(n / 2)個(gè)序列,排序后每個(gè)序列包含兩個(gè)元素
            2.     將上述序列再次歸并,形成floor(n / 4)個(gè)序列,每個(gè)序列包含四個(gè)元素
            3.     重復(fù)步驟2,直到所有元素排序完畢
                 歸并操作的過程如下:
            1.     申請(qǐng)空間,使其大小為兩個(gè)已經(jīng)排序序列之和,該空間用來存放合并后的序列
            2.     設(shè)定兩個(gè)指針,最初位置分別為兩個(gè)已經(jīng)排序序列的起始位置
            3.     比較兩個(gè)指針?biāo)赶虻脑兀x擇相對(duì)小的元素放入到合并空間,并移動(dòng)指針到下一位置
            4.     重復(fù)步驟3直到某一指針達(dá)到序列尾
            5.     將另一序列剩下的所有元素直接復(fù)制到合并序列尾

            自底向上歸并,如圖所示:



            遞歸實(shí)現(xiàn)代碼:

            #include <iostream>
             
             using namespace std;
             
             void merge(int*arr, int p, int q, int r)
             {
                 int n1 = q - p + 1;
                 int n2 = r - q;
             
                 int* L = new int[n1];
                 int* R = new int[n2];
             
                 for(int i = 0; i < n1; i++)
                 {
                     L[i] = arr[p + i];
                 }
                 for(int j = 0; j < n2; j++)
                 {
                     R[j] = arr[q + j + 1];
                 }
             
                 int i = 0;
                 int j = 0;
                 int k = p;
             
                 while((i < n1) && (j < n2))
                 {
                     if(L[i] <= R[j])
                     {
                         arr[k] = L[i];
                         i++;
                     }
                     else
                     {
                         arr[k] = R[j];
                         j++;
                     }
                     k++;
                 }
             
                 if (i < n1)
                 {
                     for(; i < n1; i++, k++)
                     {
                         arr[k] = L[i];
                     }
                 }
                 if (j < n2)
                 {
                     for(; j < n2; j++, k++)
                     {
                         arr[k] = R[j];
                     }
                 }
             }
             
             void mergesort(int* arr, int p, int r)
             {
                 int q = 0;
                 if(p < r)
                 {
                     q = (p + r) / 2;
                     mergesort(arr, p, q);
                     mergesort(arr, q + 1, r);
                     merge(arr, p, q, r);
                 }
             }
             
             int main()
             {
                 int a[] = {5, 2, 4, 7, 1, 3, 2, 6};
                 mergesort(a, 0, 7);
                 for(int i = 0; i < 8; i++)
                 {
                     cout << a[i] << " ";
                 }
                 cout << endl;
                 return 0;
             }

            非遞歸代碼實(shí)現(xiàn):

            /**
              * merge_sort: 非遞歸實(shí)現(xiàn) --迭代
              * 非遞歸思想: 將數(shù)組中的相鄰元素兩兩配對(duì)。用merge函數(shù)將他們排序,
              * 構(gòu)成n/2組長(zhǎng)度為2的排序好的子數(shù)組段,然后再將他們排序成長(zhǎng)度為4的子數(shù)組段,
              * 如此繼續(xù)下去,直至整個(gè)數(shù)組排好序。
             *
            */

             #include <stdio.h>
             #include <stdlib.h>

             // merge_sort(): 非遞歸實(shí)現(xiàn)-自底向上
             
            // 將原數(shù)組劃分為left[minmax] 和 right[minmax]兩部分
             void merge_sort(int *list, int length)
             {
                 int i, left_min, left_max, right_min, right_max, next;
                 int *tmp = (int*)malloc(sizeof(int) * length);

                 if (tmp == NULL)
                 {
                     fputs("Error: out of memory\n", stderr);
                     abort();
                 }

                 for (i = 1; i < length; i *= 2) // i為步長(zhǎng),1,2,4,8……
                 {
                     for (left_min = 0; left_min < length - i; left_min = right_max)
                     {
                         right_min = left_max = left_min + i; //right_min取left_max的值,以下要用到left_max的值才不會(huì)改變left_max原先值
                         right_max = left_max + i;

                         if (right_max > length) //如果right_max超出了數(shù)組長(zhǎng)度,則right_max等于數(shù)組長(zhǎng)度
                             right_max = length;

                         next = 0;
                         while (left_min < left_max && right_min < right_max) //tmp[next]存儲(chǔ)子數(shù)組中的最小值
                             tmp[next++] = list[left_min] > list[right_min] ? list[right_min++] : list[left_min++];

                         while (left_min < left_max)  //如果left_min小于left_max,則將最小值原封不動(dòng)地賦給list[--right_min],right_min 要先減1
                             list[--right_min] = list[--left_max];

                         while (next > 0) //將tmp[next]存儲(chǔ)的最小值放入list[--right_min]中
                             list[--right_min] = tmp[--next];
                     }
                     if(i == 1) //打印第一次歸并后的數(shù)字排列
                     {
                         for(int j=0;j<length;j++)
                           printf("%d ",list[j]);
                         printf("\n");
                     }
                 }

                 free(tmp);

             }


             int main()
             {
                 int a[1000],t,i;
                 scanf("%d",&t);
                 for(i=0;i<t;i++)
                 {
                     scanf("%d",&a[i]);
                 }
                 merge_sort(a, t);

                 // print array
                 for (i = 0; i < t; i++)
                     printf("%d ", a[i]);

                 return 0;
             }
            久久久久亚洲av无码专区| 色婷婷综合久久久久中文一区二区 | 久久久久国产一区二区三区| 久久久久99精品成人片牛牛影视| 亚洲а∨天堂久久精品9966| 亚洲人成网站999久久久综合| 久久精品人人做人人爽97| 国产一区二区精品久久岳| 欧美国产成人久久精品| 嫩草影院久久99| 久久久久久综合网天天| 欧美综合天天夜夜久久| 久久人妻无码中文字幕| 精品一久久香蕉国产线看播放| 亚洲欧美一级久久精品| 久久中文字幕一区二区| 久久久久se色偷偷亚洲精品av| 2020最新久久久视精品爱 | 国产精品久久久久久吹潮| 久久精品无码免费不卡| 91久久精品91久久性色| 亚洲人成电影网站久久| 国产福利电影一区二区三区久久老子无码午夜伦不 | 亚洲人成精品久久久久| 国产亚洲成人久久| 潮喷大喷水系列无码久久精品| 99久久亚洲综合精品成人| 无码超乳爆乳中文字幕久久| 天天综合久久一二三区| 久久性生大片免费观看性| 国产91久久综合| 久久er国产精品免费观看8| 精品久久一区二区三区| 久久99国产精品久久99| 丁香五月网久久综合| 久久久噜噜噜久久熟女AA片| 麻豆亚洲AV永久无码精品久久| 午夜久久久久久禁播电影| 精品人妻久久久久久888| 久久狠狠高潮亚洲精品| 狠色狠色狠狠色综合久久|