P 1035 插入與歸併

2021-10-19 05:15:19 字數 4372 閱讀 8278

轉跳點 :?

1035 插入與歸併 (25分)

根據維基百科的定義:

插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。

歸併排序進行如下迭代操作:首先將原始序列看成 n 個只包含 1 個元素的有序子串行,然後每次迭代歸併兩個相鄰的有序子串行,直到最後只剩下 1 個有序的序列。

現給定原始序列和由某排序演算法產生的中間序列,請你判斷該演算法究竟是哪種排序演算法?

輸入在第一行給出正整數 n (≤100);隨後一行給出原始序列的 n 個整數;最後一行給出由某排序演算法產生的中間序列。這裡假設排序的目標序列是公升序。數字間以空格分隔。

首先在第 1 行中輸出insertion sort表示插入排序、或merge sort表示歸併排序;然後在第 2 行中輸出用該排序演算法再迭代一輪的結果序列。題目保證每組測試的結果是唯一的。數字間以空格分隔,且行首尾不得有多餘空格。

10

3 1 2 8 7 5 9 4 6 0

1 2 3 7 8 5 9 4 6 0

insertion sort

1 2 3 5 7 8 9 4 6 0

10

3 1 2 8 7 5 9 4 0 6

1 3 2 8 5 7 4 9 0 6

merge sort

1 2 3 8 4 5 7 9 0 6

這道題比較有意思,需要用到歸併排序和插入排序的知識,兩種排序的部落格我都寫了,自行轉跳。

這道題有兩種解法,

第一種是寫兩個排序演算法,每執行完一輪就比較一次,時間複雜度 t(o) = o(n^3+n^2logn),太暴力了

第二種是利用插入排序的特性:插入排序,前面是排好序的,後面是與初始序列相同。只要符合這個條件的就是插入,不符合就是歸併

用第一種方法暴力就行,但是第二種就需要對歸併和插入排序十分熟悉,因為要寫乙個單步的歸併和插入。插入的單步十分容易實現只要知道第幾個沒排好,繼承索引,找到位置插入就行了。而歸併就有些麻煩,需要完完整整的歸併。

ac**

1 #include 2 #include 3 #include 4 

5 int merge = 0;

6 void insertsorted(int arr, int mid, int n);

7 void mergesorted(int arr, int mid, int n);

8 int arrayequal(int arr, int ary, int n);

9 void arrayprint(int arr, int n);

10 11 int main(void)

12 25

26 for (int i = 0; i < n; i++)

27

30

31 insertsorted(arr, mid, n);

32 if (merge)

33

36 37 return 0;

38 }

39 40 //插入排序

41 void insertsorted(int arr, int mid, int n)

42 54 arr[j] = temp;

55 56 if (arrayequal(arr, mid, n))

57

65 arr[j] = temp;

66 printf("insertion sort\n");

67 arrayprint(arr, n);

68 merge = 0;

69 return;

70 }

71 }

72 merge = 1;

73 }

74 75 void mergeadd(int arr, int left, int mid, int right, int *tmp)

76 84 while (i <= mid)

85

88 while (j <= right)

89

92 //把tmp中的內容拷給arr陣列中

93 //進行歸併的時候,處理的區間是arr[left,right),對應的會把

94 //這部分區間的陣列填到tmp[left,right)區間上

95 memcpy(arr + left, tmp + left, sizeof(int) * (right - left + 1));

96 }

97 98 void mergesort(int arr, int len, int *tmp, int mid, int n)

99 104 int flag = 0;

105

106 //定義乙個步長gap,初始值為1,相當於每次只合併兩個長度為1的元素

107 for (int gap = 1; gap <= len; gap *= 2)

108

117 int end = mid + gap;

118 if (end >= len)

119

122 mergeadd(arr, beg, mid, end, tmp);

123 }

124 if (flag)

125

130 if (arrayequal(arr, mid, n))

131

134 }

135 }

136 //歸併排序介面

137 void mergesorted(int arr, int mid, int n)

138

143 //輸出陣列

144 void arrayprint(int arr, int n)

145

150 }

151 //判斷相等

152 int arrayequal(int arr, int ary, int n)

153

160 }

161 return 1;

162 }

第二種:

1 #include 2 #include 3 

4 int isinsertion(int n, int num, int mid);

5 int nextmerge(int n, int num, int mid);

6 int cmp(const void *a, const void *b)

7 8 int main()

9 17 for (i = 0; i < n; i++)

18

21 22 if (isinsertion(n, num, mid))

23

26 27 for (i = 0; i < n; i++)

28

31 return 0;

32 }

33 34 int isinsertion(int n, int num, int mid)

35 41 for (i++, lenth = i; i < n && mid[i] == num[i]; i++)

42

45 if (i < n)

46

49 printf("insertion sort\n");

50 lenth++;

51 qsort(num, lenth, sizeof(int), cmp);

52 return 0;

53 }

54 55 int nextmerge(int n, int num, int mid)

56 67 qsort(num + j * lenth, n % lenth, sizeof(int), cmp);

68 }

69 return 0;

70 }

偷懶了,用qsort」實現「歸併

pta不易,諸君共勉!

1035 插入與歸併

題目是pat乙級 思路 簡單修改插入排序和合併排序源 加入和目標比較若相等,就退出。注意 插入排序不是從第0個元素開始,是從第1個元素開始的。訓練目的 插入排序 合併排序 題目描述 根據維基百科的定義 插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出...

1035 插入與歸併

時間限制 200 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 chen,yue 根據維基百科的定義 插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全...

1035 插入與歸併

1035 插入與歸併 25 分 根據維基百科的定義 插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。歸併排序進行如下迭代操作 首先將原始序列看成 n 個只包含 1 個元素的有序子串行,然...