linux编程实现排序n个数,linux上归并排序(MergeSort)算法的C语言实现

linux下归并排序(MergeSort)算法的C语言实现

在Linux下实现了一个归并排序的算法,分成多个文件,这里记录三点:归并排序的算法、makefile的使用、gdb调试心得

一、归并排序算法

算法的递推关系:一个大的数列需要排序,把它从中间分成两部分,每一部分归并排序,然后把排好序的这两个部分再合并起来(合并的时候要按顺序合并)。

算法的Base Case:如果分成的这部分只有一个数,那么这个部分就不用再排序(看做已经排好序的)。

实现这个算法用了三个函数,每个函数在一个文件中,分别为:merge.c  sort.c 和 main.c,其中merge.c实现的是合并的方法,sort.c实现的是排序的方法,main.c是一个测试实例。还有三个头文件,分别指出了函数原型。

merge.c:

/*This is a merge program.

* Given an integer ARRAY and three numbers which indicate the begain

*and the end of two subarrays, merge the two subarrays to a bigger

*one. The two subarrays are alrealy sorted from small to big.

* For example, given an array a[10] and three numbers 0, 3 and 5. The

*first array is from a[0] to a[2], the seconde array is from a[3] to

*a[4]. The number 3 and 5 are the upper side. This program merge the

*two arrays together.

*

*/

#include

#include

#include "main.h"

void merge(int *a, int idxa, int idxb, int idxc)

{

int i = idxa, j = idxb, k = 0;

int total = idxc-idxa;

//int temp[total] = {0};

int *temp = (int *)malloc(sizeof(int) * total);

if(temp == NULL)

{

fprintf(stderr, "malloc error in merge function\n");

return;

}

while(i < idxb && j < idxc)

{

if(a[i] < a[j])

temp[k++] = a[i++];

else

temp[k++] = a[j++];

}

if(i == idxb)

{

while(j < idxc)

temp[k++] = a[j++];

}

else if(j == idxc)

{

while(i < idxb)

temp[k++] = a[i++];

}

/*Copy the temp to the sorce array*/

for(i = 0, k = idxa; i < total; k++, i++)

a[k] = temp[i];

free(temp);

}

#ifndef MAIN

/*For test*/

int main()

{

int a[10];

int i = 0;

int idxa=1, idxb=5, idxc=8;

printf("Please input 10 numbers to the array:");

for(i = 0; i < 10; i++)

scanf("%d", &a[i]);

printf("Three indexes are %d, %d and %d.\nThe first subarray is:", idxa, idxb, idxc);

for(i = idxa; i < idxb; i++)

printf(" %d", a[i]);

printf("\nThe second subarray is:");

for(i = idxb; i < idxc; i++)

printf(" %d", a[i]);

printf("\n");

merge(a, idxa, idxb, idxc);

printf("The merged array is:");

for(i = idxa; i < idxc; i++)

printf(" %d", a[i]);

printf("\n");

return 0;

}

#endif

merge.h:

/*Author: Eric

*Time: 2011.01.08

*/

void merge(int *a, int idxa, int idxb, int idxc);

sort.c:

/*This is a function for sorting an array useing merge.c

*

*Author: Eric

*Time: 2011.01.08

*/

#include

#include "main.h"

#include "merge.h"

/*Sort array a, from a[begin] to a[upend-1]*/

void sort(int *a, int begin, int upend)

{

int n = upend - begin; /*the number to be sorted*/

/*The first array is a[idxa] to a[idxb-1]. The second is a[idxb] to a[idxc-1]*/

int idxa = begin,

idxb = ((begin+upend)%2 == 0) ? (begin+upend)/2 : (begin+upend+1)/2,

idxc = upend;

if(n < 2)

{

printf("The array elements are less than two. No need to sort\n");

return;

}

else if(n == 2)

merge(a, idxa, idxb, idxc);

else

{

if(idxb-idxa > 1)

sort(a, idxa, idxb);

if(idxc-idxb > 1)

sort(a, idxb, idxc);

merge(a, idxa, idxb, idxc);

}

}

#ifndef MAIN

#define MAIN

/*For test*/

int main()

{

int a[10] = {1, 4, 8, 5, 10, 25, 54, 15, 12, 2};

int i = 0;

sort(a, 0, 10);

printf("The sorted array is:");

for(i = 0; i < 10; i++)

printf(" %d", a[i]);

printf("\n");

return 0;

}

#endif

sort.h:

void sort(int *a, int begin, int upend);

main.c:

#include

#include "sort.h"

int main()

{

int a[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};

int i = 0;

sort(a, 0, 10);

printf("The sorted array is:");

for(i = 0; i < 10; i++)

printf(" %d", a[i]);

printf("\n");

return 0;

}

main.h:

#ifndef MAIN

#define MAIN

#endif

说明:在merge函数以及sort函数中,数组的下标都是非对称的。也就是说,数组是a[begin..upend-1]。所有子数组也是这样定义的。其中idxa的意思是index a。

这个算法的思想其实很简单,之所以写这么多程序完全是为了练习在在Linux下编程。更简洁的算法实现可以参看归并排序,只不过作者的数组和我的不一样。

二、makefile的使用

在Linux下编好多个文件的程序之后要用Makefile文件把它们联合起来,这样这些程序才能组成一个可以执行的程序。我的Makefile文件内容如下:

main: main.o sort.o merge.o

gcc $^ -o $@

main.o: main.c sort.h

sort.o: sort.c merge.h main.h

merge.o: merge.c main.h

clean:

-rm *.o

.PHONY: clean

运行时使用命令make CFLAGS=-g -n可以尝试运行,看Makefile文件有没有写对。真正运行的时候去掉-n选线即可。

三、gdb调试心得

display *a@10  这个命令在每次运行的时候列出数组a的10个元素

设置断点,大段大段的运行程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值