我一直在经历Introduction to Algorithms,并且一直在尝试用C编程语言实现MERGE-SORT
算法,以便更好地理解它。
这本书提出了两个伪代码:
和
虽然我理解上述程序,但在实施过程中我必须遗漏一些东西。
我必须遗漏伪代码中的某些内容,但还无法弄明白。任何有关为何发生这种情况的建议都将受到赞赏。
编辑:更新了代码和输出
/* C program for Merge Sort */
#include<stdlib.h>
#include<stdio.h>
void MERGE(int [], int , int , int );
void printArray(int [], int );
void MERGE_SORT(int [], int , int );
int main(void)
{
int A[] = { 12, 11, 13, 5, 6, 7, 2, 9 };
int arr_size = sizeof(A) / sizeof(A[0]);
printf("Given array is \n");
printArray(A, arr_size);
MERGE_SORT(A, 0, arr_size); //Fixed: Index to start from zero
printf("\nSorted array is \n");
printArray(A, arr_size);
return 0;
}
void MERGE(int A[], int p, int q, int r)
{
int i = 0;
int j = 0;
int n1 = q - p + 1; //Computing length of sub-array 1
int n2 = r - q; //Computing length of sub-array 2
int *L = malloc((n1 + 2) * sizeof(*L + 1)); //Creating Left array
int *R = malloc((n2 + 2) * sizeof(*R + 1)); //Creating Right array
for (int i = 0; i <= n1; i++) { //Fixed: <=, i start from 0
L[i] = A[p + i - 1];
}
for (int j = 0; j <= n2; j++) { //Fixed: <=, i start from 0
R[j] = A[q + j];
}
L[n1 + 1] = 99; //Placing Sentinel at the end of array
R[n2 + 1] = 99;
i = 1;
j = 1;
/*Prior to the first iteration k = p, so the subarray is empty.
Both L[i] and R[j] are the smallest elements of their arrays and have not
been copied back to A*/
for (int k = p; k <= r; k++) { //Fixed: <=
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else { //Fixed: Assignment and not condition check for A[k]
A[k] = R[j];
j++;
}
}
free(L);
free(R);
}
void MERGE_SORT(int A[], int p, int r)
{
//During first iteration p = 1 & r = 8
if (p < r) {
int q = (p + r) / 2;
MERGE_SORT(A, p, q);
MERGE_SORT(A, q + 1, r);
MERGE(A, p, q, r);
}
}
/* Function to print an array */
void printArray(int Arr[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", Arr[i]);
printf("\n");
}
答案 0 :(得分:3)
查看伪代码,发现有些东西被错误地写错了 1.您需要注意数组索引从0或1开始 2.合并for循环中的最后一个部分实际上是一个赋值,而不是条件检查。
修改:已更新代码以修复错误Stack around the variable A was corrupted
请在此处找到更正后的代码(Lookout for // Fixed for fixes)
/* C program for Merge Sort */
#include<stdlib.h>
#include<stdio.h>
void MERGE(A, p, q, r);
void printArray(Arr, size);
void MERGE_SORT(A, p, r);
int main(void)
{
int A[] = { 12, 11, 13, 5, 6, 7, 2, 9 };
int arr_size = sizeof(A) / sizeof(A[0]);
printf("Given array is \n");
printArray(A, arr_size);
MERGE_SORT(A, 0, arr_size - 1); //Fixed: Index to start from zero, arr_size - 1
printf("\nSorted array is \n");
printArray(A, arr_size);
return 0;
}
void MERGE(int A[], int p, int q, int r)
{
int i = 0;
int j = 0;
int n1 = q - p + 1; //Computing length of sub-array 1
int n2 = r - q; //Computing length of sub-array 2
int *L = malloc((n1+1) * sizeof(*L+1)); //Creating Left array
int *R = malloc((n2+1) * sizeof(*R+1)); //Creating Right array
for (int i = 0; i < n1; i++) { //Fixed: i start from 0
L[i] = A[p + i];
}
// int arr_size = sizeof(A) / sizeof(A[0]);
for (int j = 0; j < n2; j++) { //Fixed: j start from 0
R[j] = A[q + j + 1];
}
L[n1] = 99; //Placing Sentinel at the end of array
R[n2] = 99;
i = 0; //Fixed: i and j to start from 0
j = 0;
/*Prior to the first iteration k = p, so the subarray is empty.
Both L[i] and R[j] are the smallest elements of their arrays and have not
been copied back to A*/
for (int k = p; k <= r; k++) { //Fixed: <=
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else { //Fixed: Assignment and not condition check for A[k]
A[k] = R[j];
j++;
}
}
free(L);
free(R);
}
void MERGE_SORT(int A[], int p, int r)
{
//During first iteration p = 1 & r = 8
if (p < r) {
int q = (p + r) / 2;
MERGE_SORT(A, p, q);
MERGE_SORT(A, q + 1, r);
MERGE(A, p, q, r);
}
}
/* Function to print an array */
void printArray(int Arr[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", Arr[i]);
printf("\n", size);
}
希望它有所帮助。
如有任何疑问,请回复。
答案 1 :(得分:1)
以下是我对您的代码
所做的一些更改#include<stdlib.h>
#include<stdio.h>
void MERGE(int *A,int p,int q,int r);
void printArray(int *Arr,int size);
void MERGE_SORT(int *A,int p,int r);
int main(void){
int A[] = { 12, 11, 13, 5, 6, 7, 2, 9 };
int arr_size = sizeof(A) / sizeof(A[0]);
printf("Given array is \n");
printArray(A, arr_size);
MERGE_SORT(A, 0, arr_size -1); // pass the indices of the array
printf("\nSorted array is \n");
printArray(A, arr_size);
return 0;
}
void MERGE(int A[], int p, int q, int r){
int i = 0;
int j = 0;
int k; //declair it here
int n1 = q - p + 1; //Computing length of sub-array 1
int n2 = r - q; //Computing length of sub-array 2
int *L = malloc((n1) * sizeof(*L+1)); //Creating Left array
int *R = malloc((n2) * sizeof(*R+1)); //Creating Right array
for (int i = 0; i < n1; i++) { //start coping from zero
L[i] = A[p + i];
}
for (int j = 0; j < n2; j++) {
R[j] = A[q +1 + j];
}
// L[n1] = 99; we won't be needing these as to mark the end we already know the size of arrays
// R[n2] = 99;
// i = 1;
// j = 1;
/*Prior to the first iteration k = p, so the subarray is empty.
Both L[i] and R[j] are the smallest elements of their arrays and have not
been copied back to A*/
for (k = p; k < r+1 && i < n1 && j<n2; k++) {
//i & j checks weather the array has completed or not
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else {
A[k]=R[j];
j++;
}
}
// when one of the array is empty u can copy the rest of the array with out compairing
while(i<n1)
A[k++]=L[i++];
while(j<n2)
A[k++]=R[j++];
free(L);
free(R);
}
void MERGE_SORT(int A[], int p, int r)
{
//During first iteration p = 1 & r = 8
if (p < r) {
int q = (p + r) / 2;
MERGE_SORT(A, p, q);
MERGE_SORT(A, q + 1, r);
MERGE(A, p, q, r);
}
}
/* Function to print an array */
void printArray(int Arr[], int size){
int i;
for (i = 0; i < size; i++)
printf("%d ", Arr[i]);
printf("\n");
}`
首先,您没有将正确的参数传递给函数。 然后使用无穷大来表示的概念并不好,因为人们可能想要排序的数字大于那个情况,你必须增加无穷大,上面给出了另一种方法。 意思是虽然我也解决了你的代码在这里的问题,它再次与数组索引没有正确使用检查它现在它的工作:`
#include<stdlib.h>
#include<stdio.h>
void MERGE(A, p, q, r);
void printArray(Arr, size);
void MERGE_SORT(A, p, r);
int main(void)
{
int A[] = { 12, 11, 13, 5, 6, 7, 2, 9 };
int arr_size = sizeof(A) / sizeof(A[0]);
printf("Given array is \n");
printArray(A, arr_size);
MERGE_SORT(A, 1, arr_size);
printf("\nSorted array is \n");
printArray(A, arr_size);
return 0;
}
void MERGE(int A[], int p, int q, int r)
{
int i = 0;
int j = 0;
int n1 = q - p + 1; //Computing length of sub-array 1
int n2 = r - q; //Computing length of sub-array 2
int *L = malloc((n1+1) * sizeof(*L+1)); //Creating Left array
int *R = malloc((n2+1) * sizeof(*R+1)); //Creating Right array
for (int i = 1; i < n1; i++) {
L[i] = A[p + i - 1];
}
for (int j = 1; j < n2; j++) {
R[j] = A[q + j];
}
L[n1] = 99; //Placing Sentinel at the end of array
R[n2] = 99;
i = 1;
j = 1;
/*Prior to the first iteration k = p, so the subarray is empty.
Both L[i] and R[j] are the smallest elements of their arrays and have not
been copied back to A*/
for (int k = p; k < r; k++) {
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else if (A[k] == L[i])
j++;
}
free(L);
free(R);
}
void MERGE_SORT(int A[], int p, int r)
{
//During first iteration p = 1 & r = 8
if (p < r) {
int q = (p + r) / 2;
MERGE_SORT(A, p, q);
MERGE_SORT(A, q + 1, r);
MERGE(A, p, q, r);
}
}
/* Function to print an array */
void printArray(int Arr[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", Arr[i]);
printf("\n");
}