c语言通用数据类型七大排序

目录

直接插入排序

 希尔排序

直接选择排序

堆排序

冒泡排序

快速排序

快速排序递归方法

快速排序数据结构栈模拟递归方法

归并排序

完整代码

sort.h

sort.c

test.c(多线程测试代码)

测试截图(10万随机数)


gitee开源地址,完整代码

直接插入排序

//直接插入排序gap变量控制一次间隔
static void insertsort(void* a, const size_t  n, const size_t size,const size_t gap, ll (*Sort)(void const* x, void const* y))
{
	for (size_t end = 0; end < n - gap; end++)
	{
		char* pi2 = (char*)a + (end + gap) * size;
		for (size_t i = 0; i <= end; i+= gap)
		{
			char* pi1 = (char*)a + (end-i) * size;
			if (Sort(pi1, pi2)<=0)//排序比较函数
			{
				break;
			}
			else
			{
				swap(pi1, pi2, size);//交换函数
				pi2 = pi1;
			}
		}
	}
}
//直接插入排序
void InsertSort(void* a,const size_t n,const size_t size, ll (*Sort)(void const* x, void const* y))
{
	insertsort(a, n, size, 1, Sort);
}

 希尔排序

//直接插入排序gap变量控制一次间隔
static void insertsort(void* a, const size_t  n, const size_t size,const size_t gap, ll (*Sort)(void const* x, void const* y))
{
	for (size_t end = 0; end < n - gap; end++)
	{
		char* pi2 = (char*)a + (end + gap) * size;
		for (size_t i = 0; i <= end; i+= gap)
		{
			char* pi1 = (char*)a + (end-i) * size;
			if (Sort(pi1, pi2)<=0)//排序比较函数
			{
				break;
			}
			else
			{
				swap(pi1, pi2, size);//交换函数
				pi2 = pi1;
			}
		}
	}
}
//希尔排序
void ShellSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y))
{
	for (size_t gap = n; gap >1;)
	{
		gap = gap / 3 + 1;
		insertsort(a, n, size,gap,Sort);
	}
}

直接选择排序

//直接选择排序,四指针优化
void SelectSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y))
{//四指针头尾同时遍历直接选择
	char* p_left = a;//指向第一个元素
	char* p_right = p_left+size*(n-1);//指向第最后一个元素
	char* p_move_left;//遍历左指针
	char* p_move_right;//遍历右指针
	char* p_val_left ;//选出最值左元素
	char* p_val_right;//选出最值右元素
	for (; p_left < p_right; p_left += size, p_right-=size)
	{
		if (Sort(p_left, p_right) > 0)//排序比较左右是否需要交换
		{
			swap(p_left, p_right, size);//交换函数
		}
		p_val_left = p_left;
		p_val_right = p_right;
		for (p_move_left = p_left + size, p_move_right=p_right-size; p_move_left < p_move_right; p_move_left += size, p_move_right-=size)
		{
			if (Sort(p_val_left, p_move_left)>0)//排序比较函数
			{
				p_val_left = p_move_left;//更新左边最值
			}
			if (Sort(p_val_right, p_move_left) <0)//排序比较函数
			{
				p_val_right = p_move_left;//更新右边最值
			}
			if (Sort(p_val_left, p_move_right) > 0)//排序比较函数
			{
				p_val_left = p_move_right;//更新左边最值
			}
			if (Sort(p_val_right, p_move_right) < 0)//排序比较函数
			{
				p_val_right = p_move_right;//更新右边最值
			}
		}
		swap(p_val_left, p_left, size);//交换函数
		swap(p_val_right, p_right, size);//交换函数
	}
}

堆排序

//建堆
static void AdjustDwon(void* a, const size_t n, const size_t size, const size_t root, ll(*Sort)(void const* x, void const* y))
{
	size_t parent = root;//父亲节点
	//while (1)
	for (size_t child = parent * 2 + 1/*默认左孩子*/; child < n;)
	{
		char* p_parent = (char*)a + parent * size;//父亲当前指针
		char* p_left = (char*)a + child * size;//左孩子指针
		if (child +1<n)
		{
			char* p_right = p_left + size;//右孩子指针
			if (Sort(p_left, p_right)<0)//排序比较函数,选出大的那个
			{
				++child;//右孩子大默认孩子+1
			}
		}
		
		char* p_child = (char*)a + child * size;//选出的默认孩子指针
		if (Sort(p_child, p_parent)>0)//排序比较函数
		{
			swap(p_child, p_parent, size);//交换函数
			parent = child;//父亲节点更新
			child = parent * 2 + 1;//默认孩子更新
		}
		else
		{
			break;
		}
	}
}
//堆排序
void HeapSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	//建堆
	size_t root = (n - 1 - 1) / 2;/*最后一个非叶子节点*/
	for (size_t i = 0; i <= root; i++)
	{
		AdjustDwon(a, n, size, root - i, Sort);
	}
	for (size_t i = 0; i < n-1; i++)
	{
		char* p = (char*)a + (n - 1-i) * size;//从最后一位开始排序数据
		swap(a, p, size);//交换函数
		AdjustDwon(a,n-1-i, size,0, Sort);
	}	
}

冒泡排序

//冒泡排序
void BubbleSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	for (size_t i = 0; i < n-1; i++)//n-1次冒泡
	{
		bool flag = true;//判断是否已经有序
		for (char* p = a; p < (char*)a + size * (n - 1-i); p += size)//一趟冒泡
		{
			if (Sort(p, p + size) > 0)
			{
				swap(p, p + size, size);//交换函数
				flag = false;
			}
		}
		if (flag)
			break;
	}
	
}

快速排序

快速排序递归方法

//三数取中
static void* GetMidIndex(void const* left, void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	size_t n = ((char*)right - (char*)left) / size+1;
	char* mid = (char*)left + (n>>1) * size;
	if (Sort(left, mid) < 0)
		mid = left;
	if (Sort(right, mid) < 0)
		mid = right;
	return mid;
}
//快排挖坑排序单次
static void* QuicPitSort_One(void const* left, void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* begin = left;//头指针
	char* end = right;//尾指针
	char* index = GetMidIndex(left, right, size, Sort);//三数取中
	swap(index, left, size);//交换
	char* pivit = left;//坑位置
	while (begin < end)
	{
		//flag = true;
		//右边找放左边
		while (begin < end && Sort(end, pivit) >= 0)
		{
			end -= size;
		}
		if (begin < end)
		{
			swap(pivit, end, size);//交换函数,入坑
			pivit = end;//新的坑位
		}
		//左边找放右边
		while (begin < end && Sort(begin, pivit) <= 0)
		{
			begin += size;
		}
		if (begin < end)
		{
			swap(pivit, begin, size);//交换函数,入坑
			pivit = begin;//新的坑位
		}
	}
	return pivit;
}
//挖坑法递归调用函数
static void QuicPitSort_Recur(void* a,void const* left,void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	
	if (left >= right)//区间不存在或只有一个数
	{
		return;
	}
	size_t n = ((char*)right - (char*)left) / size + 1;
	if (n<=13&&n>1)
	{
		insertsort(left, n, size, 1, Sort);
		return;
	}
	char* pivit = QuicPitSort_One(left, right, size, Sort);
	QuicPitSort_Recur(a, left, pivit-size, size, Sort);//左区间排序
	QuicPitSort_Recur(a, pivit+size, right, size, Sort);//右区间排序
}
//快排递归
void QuickSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* begin = a;//头指针
	char* end = begin + size * (n - 1);//尾指针
	//递归
	QuicPitSort_Recur(a, begin, end,size, Sort);//挖坑法
}

快速排序数据结构栈模拟递归方法

文中使用的栈点击跳转

//三数取中
static void* GetMidIndex(void const* left, void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	size_t n = ((char*)right - (char*)left) / size+1;
	char* mid = (char*)left + (n>>1) * size;
	if (Sort(left, mid) < 0)
		mid = left;
	if (Sort(right, mid) < 0)
		mid = right;
	return mid;
}
//快排挖坑排序单次
static void* QuicPitSort_One(void const* left, void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* begin = left;//头指针
	char* end = right;//尾指针
	char* index = GetMidIndex(left, right, size, Sort);//三数取中
	swap(index, left, size);//交换
	char* pivit = left;//坑位置
	while (begin < end)
	{
		//flag = true;
		//右边找放左边
		while (begin < end && Sort(end, pivit) >= 0)
		{
			end -= size;
		}
		if (begin < end)
		{
			swap(pivit, end, size);//交换函数,入坑
			pivit = end;//新的坑位
		}
		//左边找放右边
		while (begin < end && Sort(begin, pivit) <= 0)
		{
			begin += size;
		}
		if (begin < end)
		{
			swap(pivit, begin, size);//交换函数,入坑
			pivit = begin;//新的坑位
		}
	}
	return pivit;
}
//挖坑法栈模拟递归
void QuicPitSort_Stack(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	stack st;
	StackINIT(&st,"char*");
	char* begin = a;//移动头指针,开始指向头元素
	char* end = begin + size * (n - 1);//移动尾指针,开始指向尾元素
	char* tmp=NULL;//入栈边界临时指针
	st.push(&st, end);//入右边界
	st.push(&st, begin);//入左边界
	char* left = NULL;//区间头指针
	char* right = NULL;//区间尾指针
	char* pivit = NULL;//单次排序返回的排好元素指针
	while (!st.empty(&st))
	{
		left = st.top(&st);//头指针
		st.pop(&st);
		right = st.top(&st);//尾指针 
		st.pop(&st);
		pivit = QuicPitSort_One(left, right, size, Sort);
		tmp=pivit + size;
		if (tmp < right)//右区间存在
		{
			st.push(&st, right);
			st.push(&st, tmp);
		}
		tmp = pivit - size;
		if (left < tmp)//左区间存在
		{
			st.push(&st, tmp);
			st.push(&st, left);
		}
	}
	st.clear(&st);
}

归并排序

void MergeSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* tmp = malloc(n*size);//开辟临时数组
	
	if (tmp == NULL)
	{
		perror("临时数组失败\n");
	}
	//memset(tmp, 0, n * size);
	size_t gap = 1;
	char* begin = a;//数组头指针,开始指向头元素
	char* end = begin + size * (n-1);//数组尾指针,指向最后一个元素
	char* Pa = NULL;//第一组遍历指针指向头
	char* Pb = NULL;//第二组遍历指针指向头
	while (gap<n)
	{
		char* begtmp = tmp;
		char* p = begin;//移动的指针
		for (p = begin; p < end; p+=(size * gap * 2))
		{
			char* begina = p;//第一组比较的头元素
			char* righta = begina + gap * size-size;//第一组比较的尾元素
			char* beginb = righta+size;//第二组比较的头元素
			char* rightb = beginb + gap * size-size;//第二组比较的尾元素


			if(righta>end)//第一组右边界超出,第二组不存在
			{
				righta = end;//修正尾元素尾数组最后一个元素
				beginb = rightb + size;//使b数组不在进去循环判断
			}
			else if (beginb>end)//第一组存在,第二组不存在
			{
				beginb = rightb + size;//使b数组不在进去循环判断
			}
			else if (rightb>end)//第二组的尾元素超出边界
			{
				rightb = end;//修正尾元素尾数组最后一个元素
			}

			 Pa = begina;//第一组遍历指针指向头
			 Pb = beginb;//第二组遍历指针指向头
			while (Pa <= righta || Pb <= rightb)
			{
				if (Pa <= righta && Pb <= rightb)//两个数组均有数的时候
				{
					if (Sort(Pa, Pb) <= 0)//比较的数符合排序标准
					{
						swap(Pa, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
						if (Pa <= righta)
							Pa += size;
					}
					else
					{
						swap(Pb, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
						if (Pb <= rightb)
							Pb += size;
					}
				}

				if (Pa > righta)//a数组放完了
				{
					for (; Pb <= rightb; Pb += size)
					{
						swap(Pb, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
					}
				}
				else if(Pb > rightb)//b数组放完了
				{
					for (; Pa <= righta; Pa += size)
					{
						swap(Pa, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
					}
				}		
			}
		}
		if (Pb <= end)//b数组还剩下元素没复制完
		{
			for (; Pb <= end; Pb += size)
			{
				swap(Pb, begtmp, size);
				begtmp += size;//指向tmp数组的下一个元素
			}
		}
		memcpy(a, tmp, n * size);//将临时数组保存的数据考回原数组
		//memset(tmp, 0, n * size);
		gap *= 2;
	}
	free(tmp);//释放临时数组
}

完整代码

sort.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<Windows.h>
#include <process.h>
typedef int  ll;


//直接插入排序
void InsertSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));
//希尔排序
void ShellSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));
//直接选择排序
void SelectSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));
//堆排序
void HeapSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));
//冒泡排序
void BubbleSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));
//快速排序
void QuickSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));
//挖坑法栈模拟递归
void QuicPitSort_Stack(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y));

void QuickSort_Thread(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y));
//归并排序
void MergeSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y));

sort.c

#include"sort.h"
#include"stack.h"
//交换函数
static void swap(void* x, void* y, const size_t n)//交换任意数据类型的函数
{
	if (x!=y)
	{
		if (n == sizeof(char))//一字节
		{
			char tmp = *(char*)x;
			*(char*)x = *(char*)y;
			*(char*)y = tmp;
		}
		else if (n == sizeof(short int))//两字节
		{
			short int tmp = *(short int*)x;
			*(short int*)x = *(short int*)y;
			*(short int*)y = tmp;
		}
		else if (n == sizeof(int))//四字节
		{
			int tmp = *(int*)x;
			*(int*)x = *(int*)y;
			*(int*)y = tmp;
		}
		else if (n == sizeof(long long))//八字节
		{
			long long tmp = *(long long*)x;
			*(long long*)x = *(long long*)y;
			*(long long*)y = tmp;
		}
		else
		{
			void* p = malloc(n);
			if (p == NULL)
			{
				perror("交换函数创建p临时空间失败");
				exit(-1);
			}
			memcpy(p, x, n);
			memcpy(x, y, n);
			memcpy(y, p, n);
			free(p);
		}
	}
}
//直接插入排序gap变量控制一次间隔
static void insertsort(void* a, const size_t  n, const size_t size,const size_t gap, ll (*Sort)(void const* x, void const* y))
{
	for (size_t end = 0; end < n - gap; end++)
	{
		char* pi2 = (char*)a + (end + gap) * size;
		for (size_t i = 0; i <= end; i+= gap)
		{
			char* pi1 = (char*)a + (end-i) * size;
			if (Sort(pi1, pi2)<=0)//排序比较函数
			{
				break;
			}
			else
			{
				swap(pi1, pi2, size);//交换函数
				pi2 = pi1;
			}
		}
	}
}
//直接插入排序
void InsertSort(void* a,const size_t n,const size_t size, ll (*Sort)(void const* x, void const* y))
{
	insertsort(a, n, size, 1, Sort);
}
//希尔排序
void ShellSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y))
{
	for (size_t gap = n; gap >1;)
	{
		gap = gap / 3 + 1;
		insertsort(a, n, size,gap,Sort);
	}
}
//直接选择排序,四指针优化
void SelectSort(void* a, const size_t n, const size_t size, ll (*Sort)(void const* x, void const* y))
{//四指针头尾同时遍历直接选择
	char* p_left = a;//指向第一个元素
	char* p_right = p_left+size*(n-1);//指向第最后一个元素
	char* p_move_left;//遍历左指针
	char* p_move_right;//遍历右指针
	char* p_val_left ;//选出最值左元素
	char* p_val_right;//选出最值右元素
	for (; p_left < p_right; p_left += size, p_right-=size)
	{
		if (Sort(p_left, p_right) > 0)//排序比较左右是否需要交换
		{
			swap(p_left, p_right, size);//交换函数
		}
		p_val_left = p_left;
		p_val_right = p_right;
		for (p_move_left = p_left + size, p_move_right=p_right-size; p_move_left < p_move_right; p_move_left += size, p_move_right-=size)
		{
			if (Sort(p_val_left, p_move_left)>0)//排序比较函数
			{
				p_val_left = p_move_left;//更新左边最值
			}
			if (Sort(p_val_right, p_move_left) <0)//排序比较函数
			{
				p_val_right = p_move_left;//更新右边最值
			}
			if (Sort(p_val_left, p_move_right) > 0)//排序比较函数
			{
				p_val_left = p_move_right;//更新左边最值
			}
			if (Sort(p_val_right, p_move_right) < 0)//排序比较函数
			{
				p_val_right = p_move_right;//更新右边最值
			}
		}
		swap(p_val_left, p_left, size);//交换函数
		swap(p_val_right, p_right, size);//交换函数
	}
}
//建堆
static void AdjustDwon(void* a, const size_t n, const size_t size, const size_t root, ll(*Sort)(void const* x, void const* y))
{
	size_t parent = root;//父亲节点
	//while (1)
	for (size_t child = parent * 2 + 1/*默认左孩子*/; child < n;)
	{
		char* p_parent = (char*)a + parent * size;//父亲当前指针
		char* p_left = (char*)a + child * size;//左孩子指针
		if (child +1<n)
		{
			char* p_right = p_left + size;//右孩子指针
			if (Sort(p_left, p_right)<0)//排序比较函数,选出大的那个
			{
				++child;//右孩子大默认孩子+1
			}
		}
		
		char* p_child = (char*)a + child * size;//选出的默认孩子指针
		if (Sort(p_child, p_parent)>0)//排序比较函数
		{
			swap(p_child, p_parent, size);//交换函数
			parent = child;//父亲节点更新
			child = parent * 2 + 1;//默认孩子更新
		}
		else
		{
			break;
		}
	}
}
//堆排序
void HeapSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	//建堆
	size_t root = (n - 1 - 1) / 2;/*最后一个非叶子节点*/
	for (size_t i = 0; i <= root; i++)
	{
		AdjustDwon(a, n, size, root - i, Sort);
	}
	for (size_t i = 0; i < n-1; i++)
	{
		char* p = (char*)a + (n - 1-i) * size;//从最后一位开始排序数据
		swap(a, p, size);//交换函数
		AdjustDwon(a,n-1-i, size,0, Sort);
	}	
}
//冒泡排序
void BubbleSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	for (size_t i = 0; i < n-1; i++)//n-1次冒泡
	{
		bool flag = true;//判断是否已经有序
		for (char* p = a; p < (char*)a + size * (n - 1-i); p += size)//一趟冒泡
		{
			if (Sort(p, p + size) > 0)
			{
				swap(p, p + size, size);//交换函数
				flag = false;
			}
		}
		if (flag)
			break;
	}
	
}
//三数取中
static void* GetMidIndex(void const* left, void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	size_t n = ((char*)right - (char*)left) / size+1;
	char* mid = (char*)left + (n>>1) * size;
	if (Sort(left, mid) < 0)
		mid = left;
	if (Sort(right, mid) < 0)
		mid = right;
	return mid;
}
//快排挖坑排序单次
static void* QuicPitSort_One(void const* left, void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* begin = left;//头指针
	char* end = right;//尾指针
	char* index = GetMidIndex(left, right, size, Sort);//三数取中
	swap(index, left, size);//交换
	char* pivit = left;//坑位置
	while (begin < end)
	{
		//flag = true;
		//右边找放左边
		while (begin < end && Sort(end, pivit) >= 0)
		{
			end -= size;
		}
		if (begin < end)
		{
			swap(pivit, end, size);//交换函数,入坑
			pivit = end;//新的坑位
		}
		//左边找放右边
		while (begin < end && Sort(begin, pivit) <= 0)
		{
			begin += size;
		}
		if (begin < end)
		{
			swap(pivit, begin, size);//交换函数,入坑
			pivit = begin;//新的坑位
		}
	}
	return pivit;
}
//挖坑法栈模拟递归
void QuicPitSort_Stack(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	stack st;
	StackINIT(&st,"char*");
	char* begin = a;//移动头指针,开始指向头元素
	char* end = begin + size * (n - 1);//移动尾指针,开始指向尾元素
	char* tmp=NULL;//入栈边界临时指针
	st.push(&st, end);//入右边界
	st.push(&st, begin);//入左边界
	char* left = NULL;//区间头指针
	char* right = NULL;//区间尾指针
	char* pivit = NULL;//单次排序返回的排好元素指针
	while (!st.empty(&st))
	{
		left = st.top(&st);//头指针
		st.pop(&st);
		right = st.top(&st);//尾指针 
		st.pop(&st);
		pivit = QuicPitSort_One(left, right, size, Sort);
		tmp=pivit + size;
		if (tmp < right)//右区间存在
		{
			st.push(&st, right);
			st.push(&st, tmp);
		}
		tmp = pivit - size;
		if (left < tmp)//左区间存在
		{
			st.push(&st, tmp);
			st.push(&st, left);
		}
	}
	st.clear(&st);
}
//挖坑法递归调用函数
static void QuicPitSort_Recur(void* a,void const* left,void const* right, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	
	if (left >= right)//区间不存在或只有一个数
	{
		return;
	}
	size_t n = ((char*)right - (char*)left) / size + 1;
	if (n<=13&&n>1)
	{
		insertsort(left, n, size, 1, Sort);
		return;
	}
	char* pivit = QuicPitSort_One(left, right, size, Sort);
	QuicPitSort_Recur(a, left, pivit-size, size, Sort);//左区间排序
	QuicPitSort_Recur(a, pivit+size, right, size, Sort);//右区间排序
}
//快排递归
void QuickSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* begin = a;//头指针
	char* end = begin + size * (n - 1);//尾指针
	//递归
	QuicPitSort_Recur(a, begin, end,size, Sort);//挖坑法
}

//归并排序,循环
void MergeSort(void* a, const size_t n, const size_t size, ll(*Sort)(void const* x, void const* y))
{
	char* tmp = malloc(n*size);
	
	if (tmp == NULL)
	{
		perror("临时数组失败\n");
	}
	//memset(tmp, 0, n * size);
	size_t gap = 1;
	char* begin = a;//数组头指针,开始指向头元素
	char* end = begin + size * (n-1);//数组尾指针,指向最后一个元素
	char* Pa = NULL;//第一组遍历指针指向头
	char* Pb = NULL;//第二组遍历指针指向头
	while (gap<n)
	{
		char* begtmp = tmp;
		char* p = begin;//移动的指针
		for (p = begin; p < end; p+=(size * gap * 2))
		{
			char* begina = p;//第一组比较的头元素
			char* righta = begina + gap * size-size;//第一组比较的尾元素
			char* beginb = righta+size;//第二组比较的头元素
			char* rightb = beginb + gap * size-size;//第二组比较的尾元素


			if(righta>end)//第二组不存在,第一组右边界超出
			{
				righta = end;//修正尾元素尾数组最后一个元素
				beginb = rightb + size;
			}
			else if (rightb>end)//第二组的尾元素超出边界
			{
				rightb = end;//修正尾元素尾数组最后一个元素
			}

			 Pa = begina;//第一组遍历指针指向头
			 Pb = beginb;//第二组遍历指针指向头
			while (Pa <= righta || Pb <= rightb)
			{
				if (Pa <= righta && Pb <= rightb)//两个数组均有数的时候
				{
					if (Sort(Pa, Pb) <= 0)//比较的数符合排序标准
					{
						swap(Pa, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
						if (Pa <= righta)
							Pa += size;
					}
					else
					{
						swap(Pb, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
						if (Pb <= rightb)
							Pb += size;
					}
				}

				if (Pa > righta)//a数组放完了
				{
					for (; Pb <= rightb; Pb += size)
					{
						swap(Pb, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
					}
				}
				else if(Pb > rightb)//b数组放完了
				{
					for (; Pa <= righta; Pa += size)
					{
						swap(Pa, begtmp, size);
						begtmp += size;//指向tmp数组的下一个元素
					}
				}		
			}
		}
		if (Pb <= end)//b数组还剩下元素没复制完
		{
			for (; Pb <= end; Pb += size)
			{
				swap(Pb, begtmp, size);
				begtmp += size;//指向tmp数组的下一个元素
			}
		}
		memcpy(a, tmp, n * size);
		//memset(tmp, 0, n * size);
		gap *= 2;
	}
	free(tmp);//释放临时数组
}

test.c(多线程测试代码)

#define _CRT_SECURE_NO_DEPRECATE  1
#include"sort.h"
#include<time.h>
#define NUM 100000
//#define NUM 50
typedef struct sorttest
{
	int* p;
	void (*Sort)(void* a, const size_t n, const size_t size, bool (*Sort)(void* x, void* y));
	char name[50];
	bool prin;
}sorttest;

int mysort(const void* a, const void* b)
{
	return (*(int*)a - *(int*)b);//升序
	//return (*(int*)b - *(int*)a);//降序
}

int mysort_char(const void* a, const void* b)
{
	return (*(char*)a - *(char*)b);//升序
	//return (*(int*)b - *(int*)a);//降序
}
void print(int* p,size_t n)//int型数据遍历打印
{
	for (size_t i = 0; i < n; i++)
	{
		printf("%d:%d\n",i, p[i]);
	}
}
void print_char(char* p, size_t n)//char型数据遍历打印
{
	for (size_t i = 0; i < n; i++)
	{
		printf("%d:%c\n", i, p[i]);
	}
}
DWORD WINAPI test(void* p)//多线程调用函数
{
	sorttest* sort = (sorttest*)p;
	if (sort->prin)
	{
		printf("%s:排序前\n", sort->name);
		print(sort->p, NUM);
	}
	clock_t  time_front = clock();
	sort->Sort(sort->p, NUM, sizeof(int), mysort);
	clock_t time_after = clock();
	printf("%s运行了%dms\n",sort->name,time_after - time_front);
	if (sort->prin)
	{
		printf("%s:排序后\n",sort->name);
		print(sort->p, NUM);
	}
	//_endthread();
}
void testchar(void* p)
{
	sorttest* sort = (sorttest*)p;
	//sort->ThreadNum++;
	if (sort->prin)
	{
		printf("%s:排序前\n", sort->name);
		print_char(sort->p, NUM);
	}
	clock_t  time_front = clock();
	sort->Sort(sort->p, NUM, sizeof(char), mysort_char);
	clock_t time_after = clock();
	printf("%s运行了%dms\n", sort->name, time_after - time_front);
	if (sort->prin)
	{
		printf("%s:排序后\n", sort->name);
		print_char(sort->p, NUM);
	}
	_endthread();
}
int main()
{
	srand((unsigned int)time(NULL));
	int* p1 = malloc(sizeof(int) * NUM);
	int* p2 = malloc(sizeof(int) * NUM);
	int* p3 = malloc(sizeof(int) * NUM);
	int* p4 = malloc(sizeof(int) * NUM);
	int* p5 = malloc(sizeof(int) * NUM);
	int* p6 = malloc(sizeof(int) * NUM);
	int* p7 = malloc(sizeof(int) * NUM);
	int* p8 = malloc(sizeof(int) * NUM);
	int* p9 = malloc(sizeof(int) * NUM);
	char arr[NUM];
	for (size_t i = 0; i < NUM; i++)
	{
		int num = rand();
		p1[i] = num;
		p2[i] = p1[i];
		p3[i] = p1[i];
		p4[i] = p1[i];
		p5[i] = p1[i];
		p6[i] = p1[i];
		p7[i] = p1[i];
		p8[i] = p1[i];
		p9[i] = p1[i];
		arr[i] = num%26+'A';
	}
	//直接插入排序
	sorttest Insert;
	Insert.p = p1;
	Insert.Sort = InsertSort;
	strcpy(Insert.name, "InsertSort(直接插入排序)");
	//希尔排序
	sorttest Shell;
	Shell.p = p2;
	Shell.Sort = ShellSort;
	strcpy(Shell.name, "ShellSort(希尔排序)");
	//直接选择排序
	sorttest Select;
	Select.p = p3;
	Select.Sort = SelectSort;
	strcpy(Select.name, "SelectSort(直接选择排序)");
	//堆排序
	sorttest Heap;
	Heap.p = p4;
	Heap.Sort = HeapSort;
	strcpy(Heap.name, "HeapSort(堆排序)");
	//冒泡排序
	sorttest Bubble;
	Bubble.p = p5;
	Bubble.Sort = BubbleSort;
	strcpy(Bubble.name, "BubbleSort(冒泡排序)");
	//快排挖坑递归排序
	sorttest Quick;
	Quick.p = p6;
	Quick.Sort = QuickSort;
	strcpy(Quick.name, "QuickSort(快排挖坑递归排序)");

	//快排挖坑法栈模拟递归
	sorttest QuickStack;
	QuickStack.p = p7;
	QuickStack.Sort = QuicPitSort_Stack;
	strcpy(QuickStack.name, "QuickSort(快排挖坑栈模拟递归)");

	//内置排序
	sorttest Qsort;
	Qsort.p = p8;
	Qsort.Sort = qsort;
	strcpy(Qsort.name, "Qsort(内置排序)");

	//快排挖坑法栈模拟递归多线程版
	sorttest Merge;
	Merge.p = p9;
	Merge.Sort = MergeSort;
	strcpy(Merge.name, "MergeSort(归并排序)");

	Qsort.prin = 0;
	Insert.prin = 0;
	Shell.prin = 0;
	Select.prin = 0;
	Heap.prin = 0;
	Bubble.prin = 0;
	Quick.prin = 0;
	QuickStack.prin = 0;
	Merge.prin = 0;

	HANDLE handle[9];
	printf("通用数据类型九大排序\n%ld个随机数排序性能测试\n", NUM);
	handle[0] = _beginthreadex(NULL, 0, test, &Qsort, 0, NULL);//内置排序
	handle[1] = _beginthreadex(NULL, 0, test, &Insert, 0, NULL);//插入排序
	handle[2] = _beginthreadex(NULL, 0, test, &Shell ,0, NULL);//希尔排序
	handle[3] = _beginthreadex(NULL, 0, test, &Select, 0, NULL);//选择排序
	handle[4] = _beginthreadex(NULL, 0, test, &Heap, 0, NULL);//堆排序
	handle[5] = _beginthreadex(NULL, 0, test, &Bubble, 0, NULL);//冒泡排序
	handle[6] = _beginthreadex(NULL, 0, test, &Quick, 0, NULL);//快排挖坑递归排序
	handle[7] = _beginthreadex(NULL, 0, test, &QuickStack, 0, NULL);//快排挖坑栈模拟递归
	handle[8] = _beginthreadex(NULL, 0, test, &Merge, 0, NULL);//归并排序
	WaitForMultipleObjects(9, handle, TRUE, INFINITE);//等待多个线程结束
	printf("排序性能测试结束\n");
	return 0;
}

测试截图(10万随机数)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值