C语言归并排序算法求助
本帖最后由 little_boy 于 2020-2-21 13:08 编辑大佬们帮忙看下算法哪里有问题,编译环境:vs2019
问题已解决,感谢各位大佬的帮助,尤其是@tony666的回复让我找到了问题的所在,修改后的代码在10#
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int intCmp(void* vp1, void* vp2);
int* initialize(int* arr, int n);
void assign(void*, void*, int);
void merge(void* arr, int p, int q, int r, int elemSize, int (*cmpFunc)(void*, void*));
void mergeSort(void* arr, int p, int r, int elemSize, int (*cmpFunc)(void*, void*));
int main()
{
int n;
printf("Please input a number:");
scanf("%d", &n);
int* arr = (int*)malloc(n * sizeof(int));
clock_t start = clock();
initialize(arr, n);
clock_t end = clock();
printf("inintalize %d numbers costs %lfs\n",n, (double)(end - start)/CLOCKS_PER_SEC);
printf("排序前:\n");
for (int i = 0; i < n; i++)
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") :printf("") ;
}
start = clock();
mergeSort(arr, 0, n - 1, sizeof(int), intCmp);
end = clock();
printf("\ninsertionSort %d numbers costs %lfs\n",n, (double)(end - start) / CLOCKS_PER_SEC);
printf("排序后:\n");
for (int i = 0; i < n; i++)
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") : printf("");
}
free(arr);
return 0;
}
int* initialize(int* arr,int n)
{
for (int i = 0; i < n; i++)
{
arr = rand() % n;
}
return arr;
}
int intCmp(void* vp1, void* vp2)
{
return (*(int*)vp1) - (*(int*)vp2);
}
void assign(void* des, void* src,int elemSize)
{
for (int i = 0; i < elemSize; i++)
{
*((char*)des + i) = *((char*)src + i);
}
}
void merge(void* arr, int p, int q, int r, int elemSize, int (*cmpFunc)(void*, void*))
{
int i = p;
int j = q+1;
int k = 0;
char* temp = (char*)malloc((r-p+1)*elemSize);
while (i <= q && j <= r) {
if (cmpFunc((char*)arr + i * elemSize, (char*)arr + j * elemSize) < 0) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, elemSize);
i++;
}
else
{
assign((char*)temp + k * elemSize, (char*)arr + j * elemSize, elemSize);
j++;
}
k++;
}
if (i <= q) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, (q - i + 1) * elemSize);
}
if (j <= r) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, (r - j + 1) * elemSize);
}
assign(arr, temp, (r - p + 1) * elemSize);
free(temp);
}
void mergeSort(void* arr, int p, int r,int elemSize,int (*cmpFunc)(void*,void*))
{
int q = 0;
if (p < r) {
q = (r+p) / 2;
mergeSort(arr, p, q,elemSize,cmpFunc);
mergeSort(arr, q + 1, r, elemSize, cmpFunc);
merge(arr, p, q, r, elemSize,cmpFunc);
}
} 学了这么久,我都不会算法,羡慕楼主都会使用time.h了,好想学会malloc和库函数怎么用,
我VS2010编译楼主的程序并没有报错啊?排序是对的呀?
楼主想问的是什么呀? 把数据结构与算法分析的 c 语言实现版本拿来, 反复键入代码, 做一些测试数据进行调试, 就弄明白了
就是递归到底, 然后一层一层出栈,从左向右的.
mergeSort是分, merge是治, 合起来就是分治思想 本帖最后由 little_boy 于 2020-2-21 10:46 编辑
54sdd 发表于 2020-2-21 10:23
把数据结构与算法分析的 c 语言实现版本拿来, 反复键入代码, 做一些测试数据进行调试, 就弄明白了
就是递 ...
为什么我把算法写成具体的int型数组的排序是可行的?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void merge(int arr[], int low, int mid, int high);
void merge_sort(int arr[], int first, int last);
int* initialize(int* arr, int n);
int main()
{
int n;
printf("Please input a number:");
scanf("%d", &n);
int* arr = (int*)malloc(n * sizeof(int));
clock_t start = clock();
initialize(arr, n);
clock_t end = clock();
printf("inintalize %d numbers costs %lfs\n",n, (double)(end - start)/CLOCKS_PER_SEC);
printf("排序前:\n");
for (int i = 0; i < n; i++)
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") :printf("") ;
}
start = clock();
merge_sort(arr, 0, n - 1);
end = clock();
printf("\ninsertionSort %d numbers costs %lfs\n",n, (double)(end - start) / CLOCKS_PER_SEC);
printf("排序后:\n");
for (int i = 0; i < n; i++)
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") : printf("");
}
free(arr);
return 0;
}
void merge(int arr[], int low, int mid, int high)
{
int i, k;
int* tmp = (int*)malloc((high - low + 1) * sizeof(int));
int left_low = low;
int left_high = mid;
int right_low = mid + 1;
int right_high = high;
k = 0;
while (left_low <= left_high && right_low <= right_high)
{
if (arr < arr)
tmp = arr;
else {
tmp = arr;
}
}
while (left_low <= left_high) {
tmp = arr;
}
while (right_low <= right_high) {
tmp = arr;
}
for (i = 0; i < high - low + 1; i++)
arr = tmp;
free(tmp);
}
void merge_sort(int arr[], int first, int last) {
int mid = 0;
if (first < last)
{
mid = (first + last) / 2;
merge_sort(arr, first, mid);
merge_sort(arr, mid + 1, last);
merge(arr, first, mid, last);
}
}
int* initialize(int* arr,int n)
{
for (int i = 0; i < n; i++)
{
arr = rand() % n;
}
return arr;
}
小菜鸟一枚 发表于 2020-2-21 10:21
学了这么久,我都不会算法,羡慕楼主都会使用time.h了,好想学会malloc和库函数怎么用,
我VS2010编译楼主 ...
编译运行可以但是完成不了排序的功能 本帖最后由 我的爱是你 于 2020-2-21 12:29 编辑
作为一个小白,一步一步看你代码到栈操作,我就知道后面排序不用看了。{:301_1005:}
这是你原来的运算结过,明显错误。
这是我改后的:
下面代码,自己好好想想自己写的栈怎么做的。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int intCmp(void* vp1, void* vp2);
int* initialize(int* arr, int n);
void assign(void*, void*, int);
void merge(void* arr, int p, int q, int r, int elemSize, int (*cmpFunc)(void*, void*));
void mergeSort(void* arr, int p, int r, int elemSize, int (*cmpFunc)(void*, void*));
int main()
{
int n;
printf("Please input a number:");
scanf_s("%d", &n);
int* arr = (int*)malloc(n * sizeof(int));//分配一个数组
clock_t start = clock(); //返回运行时间毫秒
initialize(arr, n);
clock_t end = clock(); //赋值后再次计算运行时间
printf("inintalize %d numbers costs %lfs\n", n, (double)(end - start) / CLOCKS_PER_SEC); //输出列输出秒
printf("排序前:\n");
for (int i = 0; i < n; i++) //输出数组
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") : printf(""); //输出10位换行
}
start = clock(); //毫秒
mergeSort(arr, 0, n - 1, sizeof(int), intCmp); //数组,0,列,4,,0
end = clock();
printf("\ninsertionSort %d numbers costs %lfs\n", n, (double)(end - start) / CLOCKS_PER_SEC);
printf("排序后:\n");
for (int i = 0; i < n; i++)
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") : printf("");
}
free(arr);
return 0;
}
int* initialize(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
arr = rand() % n; //对数组进行赋值
}
return arr;
}
int intCmp(void* vp1, void* vp2)//返回 vp1 - vp2的值
{
return (*(int*)vp1) - (*(int*)vp2);
}
void assign(void* des, void* src, int elemSize)
{
for (int i = 0; i < elemSize; i++)
{
*((char*)des + i) = *((char*)src + i);
}
}
void merge(void* arr, int p, int q, int r, int elemSize, int (*cmpFunc)(void*, void*))
{
int i = p;
int j = q + 1;
int k = 0;
char* temp = (char*)malloc((r - p + 1) * elemSize);
while (i <= q && j <= r) {
if (cmpFunc((char*)arr + i * elemSize, (char*)arr + j * elemSize) < 0) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, elemSize);
i++;
}
else
{
assign((char*)temp + k * elemSize, (char*)arr + j * elemSize, elemSize);
j++;
}
k++;
}
if (i <= q) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, (q - i + 1) * elemSize);
}
if (j <= r) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, (r - j + 1) * elemSize);
}
assign(arr, temp, (r - p + 1) * elemSize);
free(temp);
}
void mergeSort(void* arr, int p, int r, int elemSize, int (*cmpFunc)(void*, void*))
{
int q = 0;
if (p < r) {
q = (r + p) / 2; //二分
mergeSort(arr, p, q, elemSize, cmpFunc);//栈操作,后两位无意义
//mergeSort(arr, q + 1, r, elemSize, cmpFunc); //?
merge(arr, p, q, r, elemSize, cmpFunc);
}
}
本帖最后由 tony666 于 2020-2-21 12:10 编辑
楼主很厉害哈,没啥大问题,学习了
1.建议使用随机数前先设种子
int* initialize(int* arr,int n)
{
srand(time(NULL));
for (int i = 0; i < n; i++)
{
arr = rand() % n;
}
return arr;
2. 应该是手滑了 j写成了i
if (j <= r) {
assign((char*)temp + k * elemSize, (char*)arr + j * elemSize, (r - j + 1) * elemSize);
}
3.temp复制到arr时地址不对,
assign((void*)((int*)arr+p), temp, (r - p + 1) * elemSize);
free(temp); 我的爱是你 发表于 2020-2-21 11:48
作为一个小白,一步一步看你代码到栈操作,我就知道后面排序不用看了。
这是你原来的运算结过 ...
虽然不是这里的问题,不过还是非常感谢你的热心回答。 本帖最后由 little_boy 于 2020-2-21 12:57 编辑
谢谢,多谢帮助,现在解决了。
纠正后的代码
assign((char*)arr+p*elemSize, temp, (r - p + 1) * elemSize); 本帖最后由 little_boy 于 2020-2-21 13:18 编辑
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int intCmp(void* vp1, void* vp2);
int* initialize(int* arr, int n);
void assign(void*, void*, int);
void merge(void* arr, int p, int q, int r, int elemSize, int (*cmpFunc)(void*, void*));
void mergeSort(void* arr, int p, int r, int elemSize, int (*cmpFunc)(void*, void*));
int main()
{
int n;
printf("Please input a number:");
scanf_s("%d", &n);
int* arr = (int*)malloc(n * sizeof(int));//分配一个数组
clock_t start = clock(); //返回运行时间毫秒
initialize(arr, n);
clock_t end = clock(); //赋值后再次计算运行时间
printf("inintalize %d numbers costs %lfs\n", n, (double)(end - start) / CLOCKS_PER_SEC); //输出列输出秒
printf("排序前:\n");
for (int i = 0; i < n; i++) //输出数组
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") : printf(""); //输出10位换行
}
start = clock(); //毫秒
mergeSort(arr, 0, n - 1, sizeof(int), intCmp); //数组,0,列,4,,0
end = clock();
printf("\ninsertionSort %d numbers costs %lfs\n", n, (double)(end - start) / CLOCKS_PER_SEC);
printf("排序后:\n");
for (int i = 0; i < n; i++)
{
printf("%-5d ", arr);
(i + 1) % 10 == 0 ? printf("\n") : printf("");
}
free(arr);
return 0;
}
int* initialize(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
arr = rand() % n; //对数组进行赋值
}
return arr;
}
int intCmp(void* vp1, void* vp2)//返回 vp1 - vp2的值
{
return (*(int*)vp1) - (*(int*)vp2);
}
void assign(void* des, void* src, int elemSize)
{
for (int i = 0; i < elemSize; i++)
{
*((char*)des + i) = *((char*)src + i);
}
}
void merge(void* arr, int p, int q, int r, int elemSize, int (*cmpFunc)(void*, void*))
{
int i = p;
int j = q+1;
int k = 0;
char* temp = (char*)malloc((r-p+1)*elemSize);
while (i <= q && j <= r) {
if (cmpFunc((char*)arr + i * elemSize, (char*)arr + j * elemSize) < 0) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, elemSize);
i++;
}
else
{
assign((char*)temp + k * elemSize, (char*)arr + j * elemSize, elemSize);
j++;
}
k++;
}
if (i <= q) {
assign((char*)temp + k * elemSize, (char*)arr + i * elemSize, (q - i + 1) * elemSize);
}
if (j <= r) {
assign((char*)temp + k * elemSize, (char*)arr + j * elemSize, (r - j + 1) * elemSize);
}
assign((char*)arr+p*elemSize, temp, (r - p + 1) * elemSize);
free(temp);
}
void mergeSort(void* arr, int p, int r,int elemSize,int (*cmpFunc)(void*,void*))
{
int q = 0;
if (p < r) {
q = (r+p) / 2;
mergeSort(arr, p, q,elemSize,cmpFunc);
mergeSort(arr, q + 1, r, elemSize, cmpFunc);
merge(arr, p, q, r, elemSize,cmpFunc);
}
}
运行结果:
页:
[1]