归并排序
别人非科班出生,亦未有人指导,纯属自学,难免有错误,恳请指导!
_________________________________________________________________
归并排序:
分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列
解决:使用归并排序递归地排序两个子序列
合并:合并两个已排序的子序列以产生排序的答案
MERGE_SORT(A, p, r)
if p < r
q = (p + r) /2
MERGE_SORT(A, p, q)
MERGE_SORT(A, q+1, r)
MERGE(A, p, q, r)
MERGE(A, p, q, r)
n1 = q - p + 1
n2 = r - q
new L[n1+1]
new R[n2+1]
for i = 1 to n1
L[i] = A[p + i -1]
for j = 1 to n2
R[j] = A[q + j]
L[n1+1] = INFINETE
R[n2+1] = INFINETE
i = 1
j = 1
for k = p to r
if L[i] <= R[j]
A[k] = L[i]
i = i+1
else A[k] = R[j]
j = j+1
/*归并排序,函数merge_sort分解序列成较小的序列,函数merge合并排序后的小序列
* @param array 待排序的输入数组
* @param lindex 数组左边界
* @param mindex 数组中间边界
* @param rindex数组右边界
*/
void merge(double array[], int lindex, int mindex, int rindex)
{
int n1 = mindex - lindex + 1;
int n2 = rindex - mindex;
double larr[n1 + 1];
double rarr[n2 + 1];
int i, j, k;
for (i = 0; i < n1; i++)
{
larr[i] = array[lindex + i];
}
for (j = 0; j < n2; j++)
{
rarr[j] = array[mindex + j + 1];
}
larr[n1] = INFINETE;
rarr[n2] = INFINETE;
i = 0;
j = 0;
for (k = lindex; k < rindex + 1; k++)
{
if (larr[i] <= rarr[j])
{
array[k] = larr[i];
i++;
}
else
{
array[k] = rarr[j];
j++;
}
}
}
/*时间复杂度theta(n*lgn)*/
void merge_sort(double array[], int lindex, int rindex)
{
if (lindex < rindex)
{
int mindex = (lindex + rindex) / 2;
merge_sort(array, lindex, mindex);
merge_sort(array, mindex + 1, rindex);
merge(array, lindex, mindex, rindex);
}
}
/*二分查找,要求待查数组是已经排好序的。
* @param array 待查找的数组
* @param value 待查元素
* @param length 待查找数组的长度
* @return 返回待查元素在数组中的索引位置,没有找到返回-1
*/
/*时间复杂的theta(lgn)*/
int binary_search(double array[], double value, int length)
{
int mid = length / 2;
int lindex = 0;
int rindex = length - 1;
while (lindex < rindex) //折半查找
{
if (rindex - lindex == 1)
{
if (value == array[rindex])
return rindex;
if (value == array[lindex])
return lindex;
break;
}
if (value < array[mid])
{
rindex = mid;
mid = lindex + (rindex - lindex + 1) / 2;
}
else if (value > array[mid])
{
lindex = mid;
mid = lindex + (rindex - lindex + 1) / 2;
}
else
{
return mid;
}
}
return -1;
}
printf("归并排序测试\n");
double arr_merge[9] = {
3, 41, 52, 26, 38, 57, 9, 49};
printf("array=");
for (int i = 0; i < 8; i++)
{
printf("%lf ", arr_merge[i]);
}
printf("\nsorted array=");
merge_sort(arr_merge, 0, 7);
for (int i = 0; i < 8; i++)
{
printf("%lf ", arr_merge[i]);
}
printf("\n..........................................\n");
printf("二分查找测试\n");
printf("sorted array=");
for (int i = 0; i < 8; i++)
{
printf("%lf ", arr_merge[i]);
}
printf("\n请输入待查元素:");
int binary_number;
scanf("%d", &binary_number);
int binary_index = binary_search(arr_merge, binary_number, 8);
printf("\nindex is %d\n", binary_index);
_________________________________________________________________
归并排序:
分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列
解决:使用归并排序递归地排序两个子序列
合并:合并两个已排序的子序列以产生排序的答案
MERGE_SORT(A, p, r)
if p < r
q = (p + r) /2
MERGE_SORT(A, p, q)
MERGE_SORT(A, q+1, r)
MERGE(A, p, q, r)
MERGE(A, p, q, r)
n1 = q - p + 1
n2 = r - q
new L[n1+1]
new R[n2+1]
for i = 1 to n1
L[i] = A[p + i -1]
for j = 1 to n2
R[j] = A[q + j]
L[n1+1] = INFINETE
R[n2+1] = INFINETE
i = 1
j = 1
for k = p to r
if L[i] <= R[j]
A[k] = L[i]
i = i+1
else A[k] = R[j]
j = j+1
/*归并排序,函数merge_sort分解序列成较小的序列,函数merge合并排序后的小序列
* @param array 待排序的输入数组
* @param lindex 数组左边界
* @param mindex 数组中间边界
* @param rindex数组右边界
*/
void merge(double array[], int lindex, int mindex, int rindex)
{
int n1 = mindex - lindex + 1;
int n2 = rindex - mindex;
double larr[n1 + 1];
double rarr[n2 + 1];
int i, j, k;
for (i = 0; i < n1; i++)
{
larr[i] = array[lindex + i];
}
for (j = 0; j < n2; j++)
{
rarr[j] = array[mindex + j + 1];
}
larr[n1] = INFINETE;
rarr[n2] = INFINETE;
i = 0;
j = 0;
for (k = lindex; k < rindex + 1; k++)
{
if (larr[i] <= rarr[j])
{
array[k] = larr[i];
i++;
}
else
{
array[k] = rarr[j];
j++;
}
}
}
/*时间复杂度theta(n*lgn)*/
void merge_sort(double array[], int lindex, int rindex)
{
if (lindex < rindex)
{
int mindex = (lindex + rindex) / 2;
merge_sort(array, lindex, mindex);
merge_sort(array, mindex + 1, rindex);
merge(array, lindex, mindex, rindex);
}
}
/*二分查找,要求待查数组是已经排好序的。
* @param array 待查找的数组
* @param value 待查元素
* @param length 待查找数组的长度
* @return 返回待查元素在数组中的索引位置,没有找到返回-1
*/
/*时间复杂的theta(lgn)*/
int binary_search(double array[], double value, int length)
{
int mid = length / 2;
int lindex = 0;
int rindex = length - 1;
while (lindex < rindex) //折半查找
{
if (rindex - lindex == 1)
{
if (value == array[rindex])
return rindex;
if (value == array[lindex])
return lindex;
break;
}
if (value < array[mid])
{
rindex = mid;
mid = lindex + (rindex - lindex + 1) / 2;
}
else if (value > array[mid])
{
lindex = mid;
mid = lindex + (rindex - lindex + 1) / 2;
}
else
{
return mid;
}
}
return -1;
}
printf("归并排序测试\n");
double arr_merge[9] = {
3, 41, 52, 26, 38, 57, 9, 49};
printf("array=");
for (int i = 0; i < 8; i++)
{
printf("%lf ", arr_merge[i]);
}
printf("\nsorted array=");
merge_sort(arr_merge, 0, 7);
for (int i = 0; i < 8; i++)
{
printf("%lf ", arr_merge[i]);
}
printf("\n..........................................\n");
printf("二分查找测试\n");
printf("sorted array=");
for (int i = 0; i < 8; i++)
{
printf("%lf ", arr_merge[i]);
}
printf("\n请输入待查元素:");
int binary_number;
scanf("%d", &binary_number);
int binary_index = binary_search(arr_merge, binary_number, 8);
printf("\nindex is %d\n", binary_index);
printf(".............................................\n");
参见《算法导论》