`

(第三章 1)通用数组(void**)的归并排序

 
阅读更多

     我简化了书上的实现,每个数组元素是void*类型,两个void*元素的大小比较通过调用者提供的回调函数typedef int (*compare_fun)(void* a, void* b);实现

 

泣血的总结:

 

        1. 减号“-”的优先级

>

  按位右移“>>”的优先级


int len=3;

printf("%d\n",len);

printf("%d\n",len>>1);

printf("%d\n",len>>1-1);

printf("%d\n",(len>>1)-1);


2. 数组越界操作,free()时运行时报错

如果数组在使用时候越界(例如,读写arr[k]内容,而k大于等于arr长度)。当使用完数组arr并释放它时,会(运行时)报错:

*** glibc detected *** : free(): invalid next size (fast)


3. 学会释放int** 或者 void**

int length=...;

...

void** arr_tmp=(void**)malloc(length*sizeof(void*)); //#include <stdlib.h>

...

free(arr_tmp);

arr_tmp=NULL;                                                                                                                                                                             

 

 

sort.h

 

#ifndef SORT_H
#define SORT_H

typedef enum _Ret{
	RET_OK,
	RET_INVALID_PARAM,
	RET_FAIL
}Ret;

typedef int (*compare_fun)(void* a, void* b);
Ret merge_sort(void** arr, int length, compare_fun compare);

#endif
 

 

sort.c

 

#include <stdlib.h>
#include "sort.h"

//int (*compare_fun)(void* a, void* b);
Ret merge_sort(void** arr, int length, compare_fun compare){

	if(length==1 || length==0)
		return RET_OK;	

	//merge_sort	-----divide
	merge_sort(arr, (int)(length>>1), compare);
	merge_sort(arr+(int)(length>>1), length-(int)(length>>1), compare);
	
	//merge		-----conquer
	void** arr_tmp=(void**)malloc(length*sizeof(void*));	//#include <stdlib.h>

	int i=0,j=length>>1,k=0;

	while(i<=(int)(length>>1)-1 && j<=(length-1)){
		if(compare((void*)arr[i],(void*)arr[j])<0){
			arr_tmp[k++]=arr[i++];
		}else{
			arr_tmp[k++]=arr[j++];
		}
	}

	while(i<=(int)(length>>1)-1){
		arr_tmp[k++]=arr[i++];
	}


	while(j<=length-1){
		arr_tmp[k++]=arr[j++];
	}


	for(i=0;i<length;i++){
		arr[i]=arr_tmp[i];
	}


	free(arr_tmp);
	arr_tmp=NULL;

	return RET_OK;
}
 

调用者程序 test.c

 

#include <stdio.h>
#include <stdlib.h>
#include "sort.h"

//C语言中void*的长度和int的长度相等吗?如果这里换成double类型呢?
int compare(void* a, void* b){
	return (int)a-(int)b;
}

void print(int* arr,int length){
	int i;
	for(i=0;i<length;i++){
		printf("%d\t",arr[i]);
	}
	printf("\n");
}

int main(void){
	int arr[]={5,3,4,2,6,3,1};

	print(arr,7);
	merge_sort((void**)arr,7,compare);
	print(arr,7);

	return 0;
}
 

 

 

 

 

 

分享到:
评论

相关推荐

    exercise6 bubble sort_冒泡排序_C++_brain7lg_

    冒泡排序是一种基础但经典的排序算法,它通过不断交换相邻的逆序元素来逐步将一个序列整理成有序状态。在C++中实现冒泡排序,我们可以...在C++中,我们还可以学习和实践其他更高效的排序算法,如快速排序、归并排序等。

    C语言练习题及答案+算法+数据结构

    - **归并排序**:分治思想,递归地将数组分成更小的部分,然后合并排序结果。 #### 3. 查找算法 - **顺序查找**:从第一个元素开始逐个比较,直到找到目标元素。 - **二分查找**:适用于有序数组,每次都将查找区间...

    排序算法-基于C语言实现的排序算法之InsertionSort实现.zip

    尽管效率不如其他高级排序算法(如快速排序、归并排序),但在小规模数据或者部分有序的数据中,插入排序的表现相当不错。 **InsertionSort步骤详解** 1. **初始化**:从第一个元素开始,该元素可以认为已经被排序...

    正反都可排序函数

    1. **选择排序**:通常情况下,选择排序只需要寻找每轮循环中的最小值,并将其放置在当前位置即可完成排序。但在本例中,为了支持正反向排序,作者通过一次遍历同时找出最小值和最大值,提高了代码的复用性和效率。 ...

    10种排序.txt

    归并排序的思想是将数组分成两半,然后递归地对这两半进行排序,最终将排序好的两半合并成一个整体。这种方法适用于大规模数据排序。 **代码示例:** ```java public static void MergeSort(int[] array) { sort...

    线性选择排序算法 算法作业的线性选择排序 算法作业的线性选择排序

    对于大数据集,更高效的排序算法如快速排序、归并排序或堆排序更为合适。 下面是C++实现线性选择排序的一个基本示例: ```cpp #include #include using namespace std; void selectionSort(vector&lt;int&gt;& arr) ...

    java在实际使用比较常用的算法

    1. **遍历**:从数组的第一个元素开始,依次比较相邻的两个元素。 2. **交换**:如果前一个元素大于后一个元素,则交换它们的位置。 3. **重复**:重复这个过程,直到没有元素需要交换。 #### Java代码示例: ```...

    qsort测试,对一般人没用

    `std::sort`的底层实现可以是快速排序、归并排序或其他高效的排序算法,但其灵活性和泛化能力使得它成为C++程序员的首选。 对比`qsort`和`std::sort`: - `qsort`更底层,适用于原始数据数组,而`std::sort`更适合...

    C#简单实现泛型选择排序

    在编程领域,排序算法是数据处理中的基础,它在各种应用中都发挥着重要作用。...而选择排序虽然在效率上不如快速排序或归并排序,但其简单的实现和固定的比较次数在某些特定场景下仍然具有一定的价值。

    算法导论答案

    ### 第3章:算法的增长率与递归 #### 3.1-1 至 3.1-8 这部分内容主要关注算法增长率的概念以及如何通过数学工具(如数学归纳法)来分析算法的时间复杂度。 #### 3.2-1 至 3.2-7 这里讨论了不同算法的时间复杂度,并...

    2021-2022计算机二级等级考试试题及答案No.2095.docx

    - **归并排序**:在所有提到的排序算法中,归并排序要求的内存量最大,因为它需要额外的空间来存储中间结果。 ### 17. Internet 的性质 - **Internet 不是一个局域网**:它是由多个网络互联构成的全球性网络。 ##...

    Java企业面试题整理及答案

    常见的排序方法包括冒泡排序、选择排序、插入排序、归并排序、快速排序等。 **快速排序实现**: ```java public class QuickSort { public static void sort(int[] arr, int low, int high) { if (arr == null || ...

    数据结构各种算法实现(C++模板) 数据结构经典实例

    **顺序表**是一种基本的数据结构,通常使用数组实现。在C++中,可以通过模板类来实现一个通用的顺序表。 ##### Seqlist.h ```cpp const int DefaultSize = 100; template class SeqList { public: SeqList(int ...

    ACM-NOI-CSP竞赛宝典策略、代码与实战经验共享-acm和noip

    - **分工合作(针对ACM)**:团队成员之间应根据各自的强项进行任务分配,例如可以一人负责读题并口头描述题目要求,另一人负责编码实现,第三人则负责审题或测试代码。 - **模板准备**:事先准备好常用的算法模板,...

    算法:C语言实现(第5部分)

    1. **时间复杂度优化**:通过算法设计,减少不必要的计算,如避免重复计算、使用更高效的排序算法(快速排序、归并排序)等。 2. **空间复杂度优化**:合理利用内存,避免过度消耗,例如,使用原地算法减少额外空间...

    数据结构各种算法实现(C++模板)

    12. **排序算法**:将一系列元素按照特定顺序(通常是从小到大)重新排列的过程,常见的排序算法有快速排序、归并排序、堆排序等。 在了解了以上概念的基础上,通过C++模板的使用,可以实现这些数据结构及其相关...

    整合了所有java经典面试题

    - Java中也可能存在内存泄漏,尤其是在使用第三方库时。内存泄漏指的是已经不再使用的对象未能被垃圾回收器及时回收,导致内存浪费。 35. **java中实现多态的机制是什么** - Java中多态的实现主要是通过继承和...

    Java企业级开发综合技能知识总结

    - 常见排序算法:冒泡排序、插入排序、选择排序、快速排序、归并排序等。 - 快速排序示例: ```java public class QuickSort { public static void sort(int[] arr, int low, int high) { if (arr == null || ...

Global site tag (gtag.js) - Google Analytics