JavaSE第三十七讲:几种常用排序算法比较

本讲内容基于上节排序算法的延伸,结合网上资料整理,只说一个大概,具体会等复习数据结构时一起讨论。

1. 冒泡排序这里可以结合上一讲冒泡排序的写法进行改进:

如果在比较完一趟之后,发现没有任何两个元素交换位置,则说明此时元素已经有序了,就不要再进行排序,可以再if语句设置一个标识量,如果交换则将这个标志量状态改变。

2. 二分查找,二分查找是属于分而治之的算法思想,时间复杂度:O(log2 n),如果是线性查找,则时间复杂度为:O(n)。

   通常时间复杂度与空间复杂度是用来衡量算法的优劣的一个主要标准。

3. 交换排序包括:冒泡排序和快速排序。

4. 交换排序思想:

   第一轮:第一个与第二比,取较小的排在首位,第一个与第三个比,取最小的排在首位....直到第一轮排完,确定整个最小元素再首位。

   第二轮:第二个与第三比,取较小的排再首位,第二个与第四个比,取最小的排在首位....直到第二轮排完,确定整个第二小元素在第二位。

   ...

   如此循环下去,直到比较完毕,确认为升序排序

5. 快速排序

   1) 递归实现

   2) 非递归实现

   快速排序思想:如序列: 5  6  4  2  3  1

   第一轮排序,取一个值,一般是取序列第一个值: 5 , 将5与其他元素一一比较,比5小的放左边,比5的放右边。

   第一轮排序过后序列为:4  2  3  1  5  6

  

   第二轮排序,则在5的左边和5的右边进行,5左边同样取第一个值 4,比4小的放4的左边,比4大的放4的右边,5右边的序列同理如此排序。

   第二轮排序过后序列为:2  3  1  4  5  6

 

   第三轮排序......

   直到整个序列比较完成,序列为:1  2  3  4  5  6 


6. 针对第三十五讲作业内容进行实现,需求为:

   随机生成 50 个数字(整数),每个数字的范围是[10, 50],统计每个数字出现的次数以及出现次数最多的数字与它的个数,最后将每个数字及其出现次数打印出来,如果某个数字出现次数为 0,则不要打印它。打印时按照数字的升序排列。 

   随机随机生成 50 个整数,有两种方法:

   1)使用java.util包下的Random类

  2)使用java.lang.Math类下Random()方法。

法一:

查看JDK Doc中的Random类,以及nextInt()方法和nextInt(int n)方法。

java.util
Class Random
   java.lang.Object
        java.util.Random

public class Random
extends Object
implements Serializable
An instance of this class is used to generate a stream of pseudorandom numbers. The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald Knuth,The Art of Computer Programming, Volume 2, Section 3.2.1.)


nextInt()方法
public int nextInt()
Returns the next pseudorandom, uniformly distributed int value from this random number generator's sequence.

nextInt(int n)方法
public int nextInt(int n)
Returns a pseudorandom, uniformly distributedint value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
Parameters:
n - the bound on the random number to be returned. Must be positive.
Returns:
the next pseudorandom, uniformly distributedint value between0 (inclusive) andn (exclusive) from this random number generator's sequence
[参数n表示:传入一个整数参数n,放回一个介于[0,n)的数,注意包含0但不包含n]
【注意】:在JDK中有一个这样的规律,像这种返回一个范围的都是左边闭区间,右边开区间。
【说明】:详细查看nextInt()方法可以知道其实是调用了 nextInt(int n)方法,一般是用nextInt(int n)这个方法,会有一个边界值的参数。
import java.util.Random;
public class RandomTest{
	public static void main(String[] args) {
		Random random = new Random();

		for(int i = 0; i < 50; i++){
			int result = random.nextInt(41);
			System.out.println(result + 10);
		}
	}
}
编译执行结果就会产生介于[0,50)之间的随机数了。

二:
查看JDK
Doc中的Math类及相应的方法
java.lang
Class Math
     java.lang.Object
     java.lang.Math

public final class Math
extends Object
The classMath contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.
[这个类里面主要是提供一些数学运算的方法]
查看random()方法:

[random()这个方法返回一个[0.0,1.0)之间的随机数]
根据上面的返回值如何将其转化为[10,50]之间的值呢?请看下面推导
0.0 <= n < 1.0  ---->  [10,50]

0.0 <= n < 41.0 //两边同时乘以41
0 <= n < 41//取整,强制类型转换(double---> int)
10 <=n < 51 //两边同时加10
即为: 10 <= n <= 50
public class RandomTest{
	public static void main(String[] args) {

		for(int i = 0; i < 50; i++){
			
			double result = Math.random();
			result = result * 41;
			int result2 = (int)result;
			result2 = result2 + 10;
			System.out.println(result2);
		}
	}
}
编译执行结果生成[10,50]之间的随机数
回到作业需求上去,实现每个数字出现的次数。
1) 产生的这些随机数[10,50]可以用数组来保存,数组长度为41。[注意数组保存的每一种数字]
2) 通过数组的值与其下标的索引来实现这个需求,很精妙哦!
import java.util.Random;
public class RandomTest2{
	public static void main(String[] args) {
		Random random = new Random();
		int[] count = new int[41]; 
		for(int i = 0; i < 50; i++){
			int number = random.nextInt(41) + 10; //[10, 50]
			System.out.println(number);
			count[number - 10]++;
		}

		for(int j = 0; j < count.length; j++){
			if(0 == count[j]){
				continue;
			}
			System.out.println((10 + j) + "appear number" + count[j]);
		}
	}
}
编译执行实现其效果:
【说明】:count[]用来存储可能会出现的数字,也就是就是出现的每一种的
数字,最多会出现41种数字,[10,50]之间。
       如果count[number - 10]等于count[10]时表示数字10出现的次数,用count[0]存储。如果10出现一次,就把count[0]+1;
        如果count[number - 10]等于count[11]时表示数字11出现的次数,用count[1]存储。如果11出现一次,就把count[1]+1;
if(0 == count[j]){
				continue;
			}
如果:数组中存在出现次数为0,则不打印。

需求3. 统计出现次数最多的数字与它的个数
		int max = count[0];
		for(int i = 0; i < count.length; i++){
			if(max < count[i]){
				max = count[i];
			}
		}
【说明】:找出出现次数最多的,有多少次。
		for(int i = 0; i < count.length; i++){
			if(max == count[i]){
				System.out.println(i + 10);
			}
		}
【说明】:将出现次数最多的这个数字打印出来

最后整个程序如下所示:
import java.util.Random;
public class RandomTest2{
	public static void main(String[] args) {
		Random random = new Random();
		int[] count = new int[41]; 
		for(int i = 0; i < 50; i++){
			int number = random.nextInt(41) + 10; //[10, 50]
			System.out.println(number);
			count[number - 10]++;
		}

		for(int j = 0; j < count.length; j++){
			if(0 == count[j]){
				continue;
			}
			System.out.println((10 + j) + "appear number" + count[j]);
		}

		int max = count[0];
		for(int i = 0; i < count.length; i++){
			if(max < count[i]){
				max = count[i];
			}
		}
		System.out.println("appear the max time" + max);
		for(int i = 0; i < count.length; i++){
			if(max == count[i]){
				System.out.println(i + 10);
			}
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值