分治与递归-线性时间选择
Posted kk980414
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治与递归-线性时间选择相关的知识,希望对你有一定的参考价值。
问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k个元素。
算法描述:
算法实现:
#include<stdio.h> #include<stdlib.h> int main() { void sord(int a[],int h,int t); int selectorder(int x,int a[],int h,int t); int partition(int a[],int h,int t,int k); int n; scanf("%d",&n); int *a; a=(int *)malloc(sizeof(int)*n); for(int i=0;i<n;i++) a[i]=rand(); for(int i=0;i<n;i++) printf("%d ",a[i]);//动态创建数组a并随机生成数组a元素、输出 /* int n=15; int a[15]={41,58,96,7,5,857,589,415,27,398,215,86,71,88,85}; for(int i=0;i<n;i++) printf("%d ",a[i]);*/ //检查程序时用的数组 printf(" "); int k; scanf("%d",&k);//输入k int answer;//order-1 if(k>n)printf("scan error");//k>n,输入错误 else { answer=selectorder(k-1,a,0,n-1);//调用selectorder函数, //得到第k小元素并赋值给answer printf("%d ",answer); } sord(a,0,n-1); for(int i=0;i<n;i++)printf("%d ",a[i]);//对数组a中元素进行选择排序、输出,为了检查程序 return 0; } void sord(int *a,int h,int t)//对数组a中(从第h个到第t个)元素进行选择排序 { int temp; int i,j; for(i=h;i<=t-1;i++) for(j=i+1;j<=t;j++) if(a[i]>a[j]) {temp=a[i];a[i]=a[j];a[j]=temp;} } int partition(int *a,int h,int t,int k)//根据元素k将数组a(从第h个到第t个) //划分成元素小于k的左半部分和大于k的右半部分 { int i=h; int j=t; int temp; while(i<j) { while(a[i]<k)i++; while(a[j]>k)j--; temp=a[i];a[i]=a[j];a[j]=temp; } for(int j=h;j<=t;j++)if(a[j]==k)break; a[j]=a[i];a[i]=k; return i; } int selectorder(int x,int *a,int h,int t) { if(t-h+1<75) { if(t>h)sord(a,h,t); return a[x]; }//如果当前数组范围内元素个数小于75, //对此范围内数组元素进行选择排序并返回a[x] else { int i; int temp; for(i=0;i<=(t-h-4)/5;i++) { sord(a,h+i*5,h+i*5+4); temp=a[h+i]; a[h+i]=a[h+i*5+2]; a[h+i*5+2]=temp; }//将n个元素划分成?n/5?个组, //对每个组进行选择排序, //将每个组的中位数调到数组前部 int k=selectorder(h+((t-h-4)/5)/2,a,h,h+(t-h-4)/5); //找出位于数组前部中每个组的中位数中的中位数 i=partition(a,h,t,k); //根据k对数组a(从第h个到第t个)进行划分, //左边元素值比k小,右边元素比k大, //返回i为k在数组中的位置 if(i==x)return(a[i]);//找到数组中第x+1小元素 else { int j=i+1; if(x<j)return selectorder(x,a,h,i-1);//从k的左半部分数组元素中找第x+1小元素 else return selectorder(x,a,j,t);//从k的右半部分数组元素中找第x+1小元素 } } }
以上是关于分治与递归-线性时间选择的主要内容,如果未能解决你的问题,请参考以下文章