排序算法--快排的优化

排序算法–快排的优化

下面是我写的一种快排:

#include <iostream>
#include <stdlib.h>

using namespace std;

void Print(int arr[],int len)
{
	int i=0;
	for(i;i<len;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
int Parition(int arr[],int first,int end)
{
	int key=arr[first];
	while(first<end)
	{
		while(first<end && arr[end]>=key)
		{
			end--;
		}
		if(first<end)
		{
			arr[first]=arr[end];
		}
		while(first<end && arr[first]<=key)
		{
			first++;
		}
		if(first<end)
		{
			arr[end]=arr[first];
		}
	}
	arr[first]=key;
	return first;
}
void Quick(int arr[],int first,int end)
{
	int k;
	if(first<end)
	{
		//最少有两个数据
		//找寻基准点
		k=Parition(arr,first,end);
		Quick(arr,first,k-1);
		Quick(arr,k+1,end);
	}
}
void QuickSort(int arr[],int len)
{
	if(arr==NULL || len<1)
	{
		return;
	}
	//快速排序就是找基准点的位置
	//将基准点大的数字放在基准点右,反之为左边
	Quick(arr,0,len-1);
}

int main()
{
	int arr[]={12,45,11,12,20,1,5,4,30,2,9};
	int len=sizeof(arr)/sizeof(int);

	Print(arr,len);
	QuickSort(arr,len);
	Print(arr,len);

	return 0;
}

我们从示例中发现,要是数组越趋于有序呢,那么我们递归的次数越来越多导致开销特别大,每次的遍历都循环遍历数组;

针对快排优化一:

  • 之前我们采用的基准数是数组的第一位,所以如果数组是有序数组的话,我们可以随机选取基准点,合理的利用rand()函数,
 - Swap(arr,first,rand()%(end-first+1)+first);//将随机值放入第一位

针对快排优化二:
我们还可以采取三数取中法;

int mid=(end-first)/2+first;
getMiddleMaxNum(arr,first,mid,end);
void getMiddleMaxNum(int arr[],int first,int mid,int end)
{
	if(arr[mid]>arr[end])
	{
		Swap(arr,mid,end);//基准点为mid 和 end中较大的数为基准点

	}
	if(arr[first]<arr[end])
	{
		Swap(arr,first,end);
	}
	if(arr[first]>arr[mid])
	{
		Swap(arr,first,mid);
	}
}

针对快排优化三:
快排呢,适用于数据量大的排序,和堆排序是适用的,那么在数据量小和数据量大的分界线处,小直接使用直接插入排序,他最快可以达到o(n);

if((end-first)<20)
{
	//数据量 直接使用插入排序
	Insert(arr,first,end);//插入排序最好的情况能达到O(n)的效率
	return;
}

针对快排优化四;
我们可以使用非递归的方式来实现快排

void Sort(int arr[],int first,int end)
{
	int* st=(int *)malloc(sizeof(int)*(end-first+1)*2);//开辟对应的空间
	//int *st=(int *)malloc(sizeof(int)*end);
	int top=0;
	st[top++]=first;
	st[top++]=end;
	int k;
	while(top!=0)
	{
		end=st[top-1];
		top--;
		first=st[top-1];
		top--;

		k=Parition(arr,first,end);

		//从右区间开始
		if(k+1<end)
		{
			//右区间至少有两个元素
			st[top++]=k+1;
			st[top++]=end;
		}
		if(first<k-1)
		{
			//左区间至少有两个元素
			st[top++]=first;
			st[top++]=k-1;
		}
	}
	free(st);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容检索、召回和排序算法是信息检索领域中常用的技术,用于从大规模数据中快速找到与用户查询相关的内容,并按照一定的规则进行排序。 1. 内容检索:内容检索是指根据用户查询的关键词或者短语,在数据集中找到所有与之相关的内容。常用的技术包括倒排索引、布尔模型和向量空间模型等。倒排索引是一种以单词为索引项,记录该单词在文档中出现位置的数据结构,可以快速定位包含特定关键词的文档。 2. 召回算法:召回算法是指从大规模数据中筛选出与用户查询相关的内容。常用的召回算法包括基于规则的匹配、TF-IDF、BM25、语义匹配等。基于规则的匹配是根据预先定义的规则,筛选出满足规则条件的内容。TF-IDF(词频-逆文档频率)和BM25(BM25评分函数)是基于词频和文档频率计算查询与文档之间的相关性的算法。语义匹配则是通过计算查询与文档之间的语义相似度来进行匹配。 3. 排序算法排序算法是指根据一定的规则将召回的内容进行排序,以便将最相关的内容排在前面。常用的排序算法包括PageRank、BM25F、LambdaRank等。PageRank是一种基于图的排序算法,通过计算网页之间的链接关系来确定网页的权重。BM25F是对BM25算法的扩展,考虑了不同字段对查询的贡献度。LambdaRank是一种机器学习算法,通过训练排序模型来优化排序结果。 这些算法通常会结合使用,以实现更准确和高效的内容检索、召回和排序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值