一、实验目的: 熟悉掌握分治算法设计技术。 二、实验要求: 1、按教材所授内容要求,完成“线性时间选择问题”算法。得到一个完整正确的程序。 2、问题规模:不少于2000 3、输出最终结果。 三、实验设备: PC机一台 四、问题描述: 运用分治法的原理,对随机生成的数进行查找,找出其中第K大小的数,找出之后输出所找到的数。 五、算法分析: Yes No 1.用到的函数: void swap(int& x,int& y);在进行查找时候用于基准元素两边的元素想交换。 void getRand(int *a);随机生成2000个-5000-5000的整数。 int partition(int a[],int left,int right); int line_select(int a[],int p,int r,int k); 2.算法分析: 利用随机分治的思想,平均时间复杂度为O(n),最坏时间复杂度为O(n2) 分治算法思路:模仿快速排序对输入数组A进行二分划分,使子数组A1的元素 <=A2中的元素,分点j由随机数产生,若k<j,则k为A1的第k小元, 若k>j, 则k为A2的第k-j小元.线性时间选择 由快速排序分点为第一个点计算。 3.进度走向 main=》getRand()=》输入I=>判断I=0?=》否=》line_select()=》退出 是=》退出 六、代码: #include <stdio.h> #include<stdlib.h> #include<time.h> #define P 0 #define R 2000 #define N 2000 #define M 10000 void swap(int& x,int& y); void getRand(int *a); int partition(int a[],int left,int right); int line_select(int a[],int p,int r,int k); void main() { printf("-----------------"); int a[N]; int k; getRand(a); printf("2000个随机数(-5000 ~ 5000)已生成-----------------\n示例(前十个):\n"); for(int l=0;l<10;l++) printf("%d ",a[l]); printf("\n"); while(1){ printf("请输入K得到第K小的数(0退出): "); scanf("%d",&k); if(k==0){break;} int i=line_select(a,P,R,k); printf("第%d小的数是: %d\n\n",k,i); } } //实现整数x和y的交换 void swap(int& x,int& y) { int t; t=x; x=y; y=t; } //生成-5000-5000的随机整数 void getRand(int *a) { srand( (unsigned)time( NULL ) ); //初始化随机数 for(int i=0;i<N;i++) { a[i]=5000-(int)rand()%M; } } //查询第k小的元素 int line_select(int a[],int p,int r,int k) { if (p==r) return a[p]; int i=partition(a,p,r); int j=i-p+1; if (k==j) return a[i]; else if (k<j) return line_select(a,p,i-1,k); else return line_select(a,i+1,r,k-j); } int partition(int a[],int p,int r) { int i=p; int j=r+1; int x=a[i]; while (true)//循环查询,输入0是退出循环 { while (a[++i]<x&&i<=r); while (a[--j]>x); if (i>j) break; swap(a[i],a[j]); } a[p]=a[j]; a[j]=x; return j; } 七、调试及运行: 1.输出第1、400、800、1200、1600、2000小的数(以500为间隔)如图: 2.输出第1、500、1000、1500、2000小的数(以500为间隔)如图: 2.输出第1、600、1200、1800、2000小的数(以600为间隔)如图: 八、实验总结 通过对分治法实现限行时间选择的复习,对快速排序的方法和基本思想有了一定的更深入了解,以一个确定的基准元素a[p]对子数组a[p:r]进行划分,可以很快速的对一个数组排序,这次实验不仅使我复习了快速排序的精髓,也练习了曾经认为不可能线性时间找到数组中第i小的数的算法。 |
算法实验--线性时间
时间: 2024-08-03 11:25:06
算法实验--线性时间的相关文章
排序算法(4)-线性时间排序
在前面三节排序算法中,我们分别分析了不同策略,思想用于排序,而这些算法都是基于数据间的比较来确定顺序的.假设我不用比较,换一种思路,那么就可以达到时间复杂度为O(n)的排序算法,当然是以付出额外的空间为代价的. 一.基本思想 线性时间排序的算法思想: (1):在计数排序中,利用比x小或等的元素个数和的来确定x位置.比如2 5 4 9 1 6.9比其余5个数都大,那就说明9 在排序后的第6个位置,这样我们只要得到比某个数大的元素个数就能得到元素在排序后数组中的位置了. (2):在桶排序中,是通过映
【经典算法】线性时间排序
在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种,如我们最常用的快速排序和堆排序等算法,这些算法需要对序列中的数据进行比较,因为被称为基于比较的排序. 基于比较的排序算法是不能突破O(NlogN)的.简单证明如下: N个数有N!个可能的排列情况,也就是说基于比较的排序算法的判定树有N!个叶子结点,比较次数至少为log(N!)=O(NlogN)(斯特林公式). 而非基于比较的排序,如计数排序,桶排序,和在此基础上的基
算法导论-- 线性时间排序(计数排序、基数排序、桶排序)
线性时间排序 前面介绍的几种排序,都是能够在复杂度nlg(n)时间内排序n个数的算法,这些算法都是通过比较来决定它们的顺序,这类算法叫做比较排序 .下面介绍的几种算法用运算去排序,且它们的复杂度是线性时间. -------------------------------------- 1.计数排序 计数排序采用的方法是:对每个元素x,去确定小于x的元素的个数,从而就可以知道元素x在输出数组中的哪个位置了. 计数排序的一个重要性质是它是稳定的,即对于相同的两个数,排序后,还会保持它们在输入数组中的
线性时间排序算法
线性时间排序算法列表 线性时间排序 Name Average Worst Memory Stable Description 计数排序 (Counting Sort) n + k n + k n + k Stable Indexes using key values. 基数排序 (Radix Sort) n * k n * k n + k Stable Examines individual bits of keys. 桶排序 (Bucket Sort) n + k n2 n * k S
读书日记- 线性时间排序算法
在最坏情况下,任何比较排序算法都需要做O(nlgn)次比较. 然而,在指定的条件下,线性时间的排序算法可以使得排序在O(n)时间内完成. 计数排序 假设n个输入元素中的每一个都是0到k区间内的一个整数,其中k为某个整数.k=O(n)时,排序运行时间为O(n). 主要思想: 创建长度为k的数组C,将对应的输入数组A的值作为索引来统计k数组每个下标出现的次数. 代码如下: void Counting_Sort(int* intArr,int* outArr,int k,int len) { int*
算法导论 第八章 线性时间排序(python)
比较排序:各元素的次序依赖于它们之间的比较{插入排序O(n**2) 归并排序O(nlgn) 堆排序O(nlgn)快速排序O(n**2)平均O(nlgn)} 本章主要介绍几个线性时间排序:(运算排序非比较排序)计数排序O(k+n)基数排序O() 第一节:用决策树分析比较排序的下界 决策树:倒数第二层满,第一层可能满的二叉树,它用来表示所有元素的比较操作{于此来分析下界},忽略控制,移动操作 1:2 #A[1]和A[2]比 <= 走左边 >走右边 <3,1,2> 最后的结果 下标对应排
算法导论 第8章 线性时间排序
合并排序和堆排序的时间复杂度为O(nlgn),插入排序和冒泡排序的时间复杂度为O(n^2),快速排序的时间复杂度在平均情况下是O(nlgn),这些排序算法都是通过对元素进行相互比较从而确定顺序的,因此都叫比较排序. 比较排序可以看做是决策树(一个满二叉树),因为每一次比较都是一个分支.n个元素的序列,其排序的结果有 n! 种可能(n个元素的全排),所以这个决策树有 n! 个叶子结点,假设树的高度为h,则有:n! <= 2^h,所以h >= lg(n!) = Ω(nlgn).一次比较排序就是从决
第九章 中位数和顺序统计量 9.2 期望为线性时间的选择算法
package chap09_Medians_and_Order_Statistics; import static org.junit.Assert.*; import java.util.Random; import org.junit.Test; public class SearchAlorithms { /** * 分割(快速排序中对数组的分割) * * @param n * @param start * @param end * @return */ protected static
【算法导论-学习笔记】以线性时间增长的排序——计数排序
计数排序是一种能够达到运行时间能够线性时间θ(n)的排序算法.在排序算法里算是最快的算法之一,当然,他有很强烈的前提.下面开始介绍一下技术排序(Counting Sort). 算法思想 计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数.这样可以用一个数组C[0..k]来记录待排序数组里元素的数量.当k=O(n)时,计数排序的运行时间为θ(n). 注:关于C[0..k],用键值对描述的话,待排序元素是键,相同元素的个数是值.例:待排序数组<2,3 , 6,4 , 1 ,