Java Day05
排序
冒泡排序
分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,可 以把最优时间复杂度降低到O(n)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定
时间复杂度O(n*n)
package com.ychs.demo;
import java.lang.reflect.Array;
import java.util.Arrays;
public class Day05_02 {
//冒泡排序 时间复杂度 n*n
public static void main(String[] args) {
int []arr = {8,5,6,7,9};
int temp = 0;
for(int i=0;i<arr.length;i++) {
for(int j=0;j<i-1;j++) {
if(arr[i]>arr[j]) {
temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
选择排序
分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- O(n^2)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 不稳定
//选择排序 时间复杂度 n*n
public static void main(String[] args) {
int []arr = {9,8,7,6,5};
int temp;
for(int i=0;i<arr.length-1;i++) {
for(int j = i+1;j<arr.length;j++) {
if(arr[i]>arr[j]) {
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
插入排序
时间复杂度最坏 O(n*n)
所需辅助空间 O(1)
public static void main(String[] args) {
int []A = new int[] {1,8,6,7};
for (int i = 1; i < 4; i++) // 类似抓扑克牌排序
{
int get = A[i]; // 右手抓到一张扑克牌
int j = i - 1; // 拿在左手上的牌总是排序好的
while (j >= 0 && A[j] > get) // 将抓到的牌与手牌从右向左进行比较
{
A[j + 1] = A[j]; // 如果该手牌比抓到的牌大,就将其右移
j--;
}
A[j + 1] = get; // 直到该手牌比抓到的牌小(或二者相等),将抓到的牌插入到该手牌右边(相等元素的相对次序未变,所以插入排序是稳定的)
}
System.out.println(Arrays.toString(A));
}
二分法排序
分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- O(nlogn)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定
public static void main(String[] args) {
int []A = new int [] {5,7,3,9};
for (int i = 1; i < 4; i++)
{
int get = A[i]; // 右手抓到一张扑克牌
int left = 0; // 拿在左手上的牌总是排序好的,所以可以用二分法
int right = i - 1; // 手牌左右边界进行初始化
while (left <= right) // 采用二分法定位新牌的位置
{
int mid = (left + right) / 2;
if (A[mid] > get)
right = mid - 1;
else
left = mid + 1;
}
for (int j = i - 1; j >= left; j--) // 将欲插入新牌位置右边的牌整体向右移动一个单位
{
A[j + 1] = A[j];
}
A[left] = get; // 将抓到的牌插入手牌
}
System.out.println(Arrays.toString(A));
}
Java自带的排序 函数
Sort()函数
Arrays里面有sort( ) 方法可以用来排序。
Arrays.toString(数组名) 以数组的形式输出数组元素
Arrays.copyOf(array,array.length) 拷贝(复制)数组
效率
排序效率由快到慢的排序:
Arrays.sort(array) > 插入排序 > 选择排序 > 冒泡排序
随机数
Math.random()
//Random 随机生成数 生成一个 double类型的0-1之间的数
System.out.println((int)Math.random()*100) ;
Random()
// 随机生成一个 整数
Random r = new Random();
System.out.println(r.nextInt());
random.nextInt()
// 随机生成0-100之内的正整数
System.out.println(r.nextInt(100));
//随机生成网站的4位的验证码
while(true) {
int a =(int)(Math.random()*10000);
if(a>=1000){
System.out.println(a);
break;}
}
案例 计算时间 运行程序需要的时间
方法返回从1970年1月1日0时0分0秒(这与UNIX系统有关)到现在的一个long型的毫秒数,取模之后即可得到所需范围内的随机数。
public static void main(String[] args)
2 {
3 int max=100,min=1;
4 long randomNum = System.currentTimeMillis();
5 int ran3 = (int) (randomNum%(max-min)+min);
6 System.out.println(ran3);
7
8 }
案例 生成4位验证码
// StringBuffer类
Random random = new Random();
StringBuffer valSb = new StringBuffer();
String charStr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSDUVWXYZ";
int charLength = charStr.length();
for (int i = 0; i < 4; i++) {
int index = random.nextInt(charLength);
valSb.append(charStr.charAt(index));
}
System.out.println(valSb.toString());
// String类
Random random = new Random();
String valSb = new String();
String charStr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSDUVWXYZ";
int charLength = charStr.length();
for (int i = 0; i < 4; i++) {
int index = random.nextInt(charLength);
valSB=charStr.charAt(charStr.charAt(index));
}
System.out.print(valSb);
Arrays 函数使用
常用函数
- Arrays.sort()
- Arrays.fill()
- Arrays.equals()
- Arrays.toString()
- Arrays.binarySearch()
- Arrays.sort()
//数组排序
int[] nums= {2,5,1,9,4};
Arrays.sort(nums);
Arrays.sort()只能给int[] 形的数组排序,不能给动态数组ArrayList排序。
Arrays.sort()按升序排序,要按降序排序的话还挺麻烦的。
并且排序后会改变原来数组的结果
2. Arrays.fill()
用于给数组填充数字
int[] nums=new int[5];
Arrays.fill(nums, 6);
- Arrays.equals()
用于对比两个数组中的元素是否一样
int[] nums1={2,6,8,1};
int[] nums2={2,6,8,1};
Arrays.equals(nums1,nums2); // true
- Arrays.toString()
将数组转化位字符串表示出来
Character[] chars= {'a','b','c'};
System.out.print(Arrays.toString(chars));
// [a, b, c]
- Arrays.binarySearch()
判断数组中是否有某个元素,有的话,返回该元素的坐标,否则返回-1
int[] nums= {3,6,8,5,1};
System.out.println(Arrays.binarySearch(nums, 3)); // 0
System.out.println(Arrays.binarySearch(nums, 0)); // -1
String 、StringBuffer、StringBuilder的区别 --(重点)
String类是不可变类,通常,String s = “abcd”;这样定义的字符串常量存在于内存中的常量池中,而String Buffer类的实例是一个可变的字符串,可以任意的拼接,它有一个toString方法用来转换为String对像。
String Buffer是线程安全的,但同时也是性能稍低下的,所以又有了String Builder类,它线程不安全,但性能略高。
注意:
string的方法函数:
1. 构造方法
2. 字符串的获取:indexOf系列是找出字符(串)在该字符串第一次出现的位置,lastIndexOf()是找出最后一次,substring()取字串等。
3. 字符串的判断:startWith,endsWith判断字符串是否以特定的字符串开头或接尾。
4. 字符串的转换:toCharArray(),toUpperCase(),toLowerCase()这三个不说了,valueOf是一个方法集,不仅可以将基本类型转换为字符串,还可以将一个引用类型的变量转换为字符串(本质上是调用引用对像的toString方法)。
getByte()方法是转成字节数组,这个在TCP/IP通信中是必要的,因为网络上流传的是字节流。
equals()是对字符串进行比较,它返回的是boolean类型。
compareTo也是比较,然而它返回的是int类,当字符串不相等时,它返回的是两个字符串第一个不相等的字符差,所以它有可能返-23这样的值。
concat(),看到它,我想起了C中的strcat这个函数。
copyValueOf(char[] …)这个还是一个字符串的获取方法。
replace,replaceFirst,replaceAll方法是用于替换的。
trim是去掉字符串两端的空格。
split方法也是处理字符串常用的方法。
charAt() 字符在某个字符位置的字符
String Buffer和String Builder的方法函数:
这两个类都有相同的添加,删除,替换,截取,反转能:
- 添加: append,insert
- 删除: delete,deleteCharAt
- 替换: replace
- 截取: substring,getChars,charAt,indexOf,lastIndexOf
- 反转:reverse
tring Builder,JDK文档有如下描述:
一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。