Insert or Merge

本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》

 

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("
");
 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
");
204     } else {
205         tmpA = malloc(n * sizeof(elementType));
206         length = findMergeSubSequenceLength(partial, n);
207         mergerPass(partial, tmpA, n, length);
208         printf("Merge Sort
");
209     }
210     printArray(partial, n);
211     return 0;
212 }
Merge or Insert

但是还有一个点无法通过,如果有大神知道,可以在下面评论告诉我

原文地址:https://www.cnblogs.com/yghjava/p/6880056.html