h2.western { font-family: "Liberation Sans", sans-serif; font-size: 16pt }
h2.cjk { font-size: 16pt }
h2.ctl { font-size: 16pt }
h1 { margin-bottom: 0.21cm }
h1.western { font-family: "Liberation Sans", sans-serif; font-size: 18pt }
h1.cjk { font-family: "Noto Sans CJK SC Regular"; font-size: 18pt }
h1.ctl { font-family: "Noto Sans CJK SC Regular"; font-size: 18pt }
pre.ctl { font-family: "Liberation Mono", monospace }
p { margin-bottom: 0.25cm; line-height: 120% }
code.ctl { font-family: "Liberation Mono", monospace }
本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》
Insert or Merge
1 Question
According to Wikipedia:
Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.
Merge sort works as follows: Divide the unsorted list into N sublists, each containing 1 element (a list of 1 element is considered sorted). Then repeatedly merge two adjacent sublists to produce new sorted sublists until there is only 1 sublist remaining.
Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in the first line either "Insertion Sort" or "Merge Sort" to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resuling sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
Sample Input 1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
Sample Output 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
Sample Input 2:
10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6
Sample Output 2:
Merge Sort
1 2 3 8 4 5 7 9 0 6
- 时间限制:400ms
- 内存限制:64MB
- 代码长度限制:16kB
- 判题程序:系统默认
- 作者:陈越
- 单位:浙江大学
2
Solution
2.1
How to Different Merge or Insertion
We
know, In merge sort,the sequence will be ordered partially,but
insertion has a point. Before this point,the sequence is
ordered,after this point,the sequence is same as the original
sequence. The insertion sort is more easily to judge. So we use
insertion method to judge which method it has used. If it is use
insertion sort,we will return the index which is the next insertion
point,then do the next insertion sort. Otherwise we will return zero
to indicate this used the merge sort.
The
code is followed:
/*
*
Judge which sorting method the system has used.If it is the insertion
merge,return the index
*
of the next insert point.Otherwise return zero
*
@param
source A <code>elementType</code> array to store the
original data
*
@parampartical
A <code>elementType</code> array to store elements which
has been sorted partial
*
@param
n The length of the array
*/
intjudgeMergeOrInsertion(elementType
source[], elementType
partial[], int
n) {
int
i;
int
min = partial[0];
int
insertPoint;
for
(i = 1; i < n; i++) {
insertPoint
= i;
if
(partial[i] > min) {
min
= partial[i];
}
else
{
break;
}
}
for
(; i < n; i++) {
if
(partial[i] != source[i]) {
return
0;
}
}
return
insertPoint;
}
2.2
How to Determine the Merge Sort Length
Algorithms
thoughts:
we
know the sequence length is 2 4 8 16,so we can let length from 2 4 8
... n
1.We
judge the length whether more than 2, we check the number whether
ordered between two sub-sequence. If all two sub-sequence is
ordered,we will check the length whether more than four. Otherwise
the length is equal two and return it.
2.we
let length increase no more than n ,we can get length and return it.
We
can use a picture to show this algorithms thoughts:
代码如下:
/*
*
Find the length of merge sort sub-sequence.
*
Algorithms thoughts:
*
we know the sequence length is 2 4 8 16,so we can let length from 2 4
8 ... n
*
1.We judge the length whether more than 2, we check the number
whether ordered between two sub-sequence. If all two sub-sequence is
ordered,we will check the length whether more than four. Otherwise
the length is equal two and return it.
*
2.we let length increase no more than n ,we can get length and return
it.
*
*
@param
partial A <code>elementType</code> array to store
elements which has been sorted partial
*
@param
n The length of the array
*
@return The length of the sub-sequence
*/
intfindMergeSubSequenceLength(intpartial[],intn){
intlength,i;
for(length=2;length<=n;length*=2){
for(i=1;i<n/length;i+=2){
if(partial[i*length-1]>partial[i*length]){
returnlength;
}
}
}
returnn;
}
完整的代码如下:
1 /* 2 * mergeOrInsert.c 3 * 4 * Created on: 2017年5月19日 5 * Author: ygh 6 */ 7 #include <stdio.h> 8 #include <stdlib.h> 9 #define MAX_LENGTH 100 10 #define MAX_VALUE 65535 11 typedef int elementType; 12 13 /* 14 *Get the input data from the command line 15 *@param source A <code>elementType</code> array to store the original data 16 *@param partical A <code>elementType</code> array to store elements which has been sorted partial 17 *@param n The length of the array 18 */ 19 void getInputData(elementType source[], elementType partial[], int n) { 20 int i; 21 elementType x; 22 for (i = 0; i < n; i++) { 23 scanf("%d", &x); 24 source[i] = x; 25 } 26 27 for (i = 0; i < n; i++) { 28 scanf("%d", &x); 29 partial[i] = x; 30 } 31 } 32 33 /* 34 * Print the array to console 35 * @param a A integer array need to sort 36 * @param n The length of the array 37 */ 38 void printArray(elementType a[], int n) { 39 int i; 40 for (i = 0; i < n; i++) { 41 if (i == n - 1) { 42 printf("%d", a[i]); 43 } else { 44 printf("%d ", a[i]); 45 } 46 } 47 printf("\n"); 48 } 49 50 /* 51 * Judge which sorting method the system has used.If it is the insertion merge,return the index 52 * of the next insert point.Otherwise return zero 53 * @param source A <code>elementType</code> array to store the original data 54 * @param partical A <code>elementType</code> array to store elements which has been sorted partial 55 * @param n The length of the array 56 */ 57 int judgeMergeOrInsertion(elementType source[], elementType partial[], int n) { 58 int i; 59 int min = partial[0]; 60 int insertPoint; 61 for (i = 1; i < n; i++) { 62 insertPoint = i; 63 if (partial[i] > min) { 64 min = partial[i]; 65 } else { 66 break; 67 } 68 } 69 for (; i < n; i++) { 70 if (partial[i] != source[i]) { 71 return 0; 72 } 73 } 74 return insertPoint; 75 } 76 77 /* 78 * Execute one time insertion sort from insertPoint 79 * @param partial A <code>elementType</code> array to store elements which has been sorted partial 80 * @param inserPoint The index of next point 81 */ 82 void insertion_sort_pass(elementType partial[], int inserPoint) { 83 int i; 84 int x = partial[inserPoint]; 85 for (i = inserPoint; i > 0; i--) { 86 if (x < partial[i - 1]) { 87 partial[i] = partial[i - 1]; 88 } else { 89 break; 90 } 91 } 92 partial[i] = x; 93 } 94 95 /* 96 * Find the length of merge sort sub-sequence. 97 * Algorithms thoughts: 98 * we know the sequence length is 2 4 8 16,so we can let length from 2 4 8 ... n 99 * 1.We judge the length whether more than 2, we check the number whether ordered between two sub-sequence. If all two sub-sequence is ordered,we will check the length whether more than four. Otherwise the length is equal two and return it. 100 * 2.we let length increase no more than n ,we can get length and return it. 101 * 102 * @param partial A <code>elementType</code> array to store elements which has been sorted partial 103 * @param n The length of the array 104 * @return The length of the sub-sequence 105 */ 106 int findMergeSubSequenceLength(int partial[], int n) { 107 int length, i; 108 for (length = 2; length <= n; length *= 2) { 109 for (i = 1; i < n / length; i += 2) { 110 if (partial[i * length - 1] > partial[i * length]) { 111 return length; 112 } 113 } 114 } 115 return n; 116 } 117 118 /* 119 * Merge sub-sequence to original array. 120 * @param a original <code>elementType</code> array to store the elements 121 * @param tmpA temporary <code>elementType</code> array to store the temporary elements 122 * @param l The start index of left sub-sequence 123 * @param r The start index of left sub-sequence 124 * @param rightEnd The end index of left sub-sequence 125 */ 126 void merge(elementType a[], elementType tmpA[], int l, int r, int rightEnd) { 127 /* 128 * lefeEnd is the r-1,the sub-sequence is adjacent 129 */ 130 int leftEnd = r - 1; 131 /* 132 * tmp is the counter of the <code>tmpA</code> 133 * we should let <code>tmpA</code> index corresponding original array 134 */ 135 int tmp = l; 136 /* 137 * Record the quantity of the all elements 138 */ 139 int numElements = rightEnd - l + 1; 140 int i; 141 while (l <= leftEnd && r <= rightEnd) { 142 if (a[l] <= a[r]) { 143 tmpA[tmp++] = a[l++]; 144 } else { 145 tmpA[tmp++] = a[r++]; 146 } 147 } 148 while (l <= leftEnd) { 149 tmpA[tmp++] = a[l++]; 150 } 151 while (r <= rightEnd) { 152 tmpA[tmp++] = a[r++]; 153 } 154 155 /* 156 * Put <code>tmpA</code> elements into the original array 157 */ 158 for (i = 0; i < numElements; i++, rightEnd--) { 159 a[rightEnd] = tmpA[rightEnd]; 160 } 161 } 162 163 /* 164 *merge ordered sub-sequence 165 * @param a original <code>elementType</code> array to store the elements 166 * @param tmpA temporary <code>elementType</code> array to store the temporary elements 167 * @param n The length of the a 168 * @param the ordered current sub-sequence length 169 */ 170 void mergerPass(elementType a[], elementType tmpA[], int n, int lenth) { 171 int i, j; 172 /* 173 * The loop will stop when meet the last two ordered sub-sequence 174 * The rest may be two sub-sequence of one sub-sequence 175 */ 176 for (i = 0; i <= n - 2 * lenth; i += lenth * 2) { 177 merge(a, tmpA, i, i + lenth, i + 2 * lenth - 1); 178 } 179 /* 180 *If the rest of is two sub-sequence 181 */ 182 if (i + lenth < n) { 183 merge(a, tmpA, i, i + lenth, n - 1); 184 } else { 185 for (j = i; j < n; j++) 186 tmpA[j] = a[j]; 187 } 188 } 189 190 int main() { 191 elementType source[MAX_LENGTH]; 192 elementType partial[MAX_LENGTH]; 193 int n; 194 int length = 0; 195 elementType *tmpA; 196 scanf("%d", &n); 197 getInputData(source, partial, n); 198 int inserPoint = judgeMergeOrInsertion(source, partial, n); 199 if (inserPoint != 0) { 200 if (inserPoint < n) { 201 insertion_sort_pass(partial, inserPoint); 202 } 203 printf("Insertion Sort\n"); 204 } else { 205 tmpA = malloc(n * sizeof(elementType)); 206 length = findMergeSubSequenceLength(partial, n); 207 mergerPass(partial, tmpA, n, length); 208 printf("Merge Sort\n"); 209 } 210 printArray(partial, n); 211 return 0; 212 }
Merge or Insert
但是还有一个点无法通过,如果有大神知道,可以在下面评论告诉我