二十八、快速查找

本文介绍了一种基于快速排序原理的快速选择算法,并提供了详细的代码实现。该算法通过使用插入排序作为辅助手段,针对小规模数据集进行优化。此外,文章还展示了如何找到未排序数组中的第K个最小元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码了,和快速排序没什么区别

#include <stdio.h>
//当元素个数达到一定数量时可以用简单的排序算法
#define CutOff 3

//插入排序
void InsertionSort(int array[], int size)
{
	int i, j, temp;
	for(i = 1; i < size; i++)
	{
		temp = array[i];
		for(j = i; j > 0 && array[j - 1] > temp; j--)
		{
			array[j] = temp;
		}
		array[j] = temp;  
	}
}

//交换两个值
void Swap(int *i, int *j)
{
	(*i) = (*i) - (*j);
	(*j) = (*i) + (*j);
	(*i) = (*j) - (*i);
}

//取中值
int Median(int array[], int left, int right)
{
	int center = (left + right)/2;
	if(array[left] > array[center])
	{
		Swap(&array[left], &array[center]);
	}
	if(array[left] > array[right])
	{
		Swap(&array[left], &array[right]);
	}
	if(array[center] > array[right])
	{
		Swap(&array[center], &array[right]);
	}
	Swap(&array[center], &array[right - 1]);
	return array[right - 1];
}

//快速选择组件
void QuickSelectComponment(int array[], int left, int right, int searchIndex)
{
	int leftPos, rightPos, piovt;
	leftPos = left;
	rightPos = right - 1;
	if(right - left >= CutOff)
	{
		piovt = Median(array, left, right);
		while(true)
		{
			while(array[++leftPos] < piovt){};
			while(array[--rightPos] > piovt){};
			if(leftPos < rightPos)
			{
				Swap(&array[leftPos], &array[rightPos]);
			}
			else
			{
				break;
			}
		}
		Swap(&array[leftPos], &array[right - 1]);
		if(searchIndex <= leftPos)
		{
			QuickSelectComponment(array, left, leftPos - 1, searchIndex);
		}
		else if(searchIndex > leftPos + 1)
		{
			QuickSelectComponment(array, leftPos + 1, right, searchIndex);
		}
	}
	else
	{
		InsertionSort(array + left, right - left + 1);
	}
}

//快速选择,返回第K个最小的数
int QuickSelect(int array[], int size, int searchIndex)
{
	if(searchIndex > size)
	{
		return EOF;
	}
	QuickSelectComponment(array, 0, size - 1, searchIndex);
	return array[searchIndex - 1];
}

int main(void)
{
	int array[] = {4,2,3,1,5,6,7};
	int size = sizeof(array)/sizeof(array[0]);
	printf("%d\n", QuickSelect(array, size, 6));
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值