数组高级(排序和查找)
排序
冒泡排序
相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
原理图:
package cn.it18zhang_01;
/*
* 数组排序之冒泡排序:
* 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
*/
public class ArrayDemo {
public static void main(String[] args) {
// 定义一个数组
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:");
printArray(arr);
/*
// 第一次比较
// arr.length - 1是为了防止数据越界
// arr.length - 1 - 0是为了减少比较的次数
for (int x = 0; x < arr.length - 1 - 0; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println("第一次比较后:");
printArray(arr);
// 第二次比较
// arr.length - 1是为了防止数据越界
// arr.length - 1 - 1是为了减少比较的次数
for (int x = 0; x < arr.length - 1 - 1; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println("第二次比较后:");
printArray(arr);
// 第三次比较
// arr.length - 1是为了防止数据越界
// arr.length - 1 - 2是为了减少比较的次数
for (int x = 0; x < arr.length - 1 - 2; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println("第三次比较后:");
printArray(arr);
// 第四次比较
// arr.length - 1是为了防止数据越界
// arr.length - 1 - 3是为了减少比较的次数
for (int x = 0; x < arr.length - 1 - 3; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println("第四次比较后:");
printArray(arr);
*/
// 既然听懂了,那么上面的代码就是排序代码
// 而上面的代码重复度太高了,所以用循环改进
// for (int y = 0; y < 4; y++) {
// for (int x = 0; x < arr.length - 1 - y; x++) {
// if (arr[x] > arr[x + 1]) {
// int temp = arr[x];
// arr[x] = arr[x + 1];
// arr[x + 1] = temp;
// }
// }
// }
/*
// 由于我们知道比较的次数是数组长度-1次,所以改进最终版程序
for (int x = 0; x < arr.length - 1; x++) {
for (int y = 0; y < arr.length - 1 - x; y++) {
if (arr[y] > arr[y + 1]) {
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
System.out.println("排序后:");
printArray(arr);
*/
//由于我可能有多个数组要排序,所以我要写成方法
bubbleSort(arr);
System.out.println("排序后:");
printArray(arr);
}
//冒泡排序代码
public static void bubbleSort(int[] arr){
for (int x = 0; x < arr.length - 1; x++) {
for (int y = 0; y < arr.length - 1 - x; y++) {
if (arr[y] > arr[y + 1]) {
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
}
// 遍历功能
public static void printArray(int[] arr) {
System.out.print("[");
for (int x = 0; x < arr.length; x++) {
if (x == arr.length - 1) {
System.out.print(arr[x]);
} else {
System.out.print(arr[x] + ", ");
}
}
System.out.println("]");
}
}
选择排序
从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
package cn.it18zhang_02;
/*
* 数组排序之选择排序:
* 从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
*/
public class ArrayDemo {
public static void main(String[] args) {
// 定义一个数组
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:");
printArray(arr);
/*
// 第一次
int x = 0;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("第一次比较后:");
printArray(arr);
// 第二次
x = 1;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("第二次比较后:");
printArray(arr);
// 第三次
x = 2;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("第三次比较后:");
printArray(arr);
// 第四次
x = 3;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("第四次比较后:");
printArray(arr);
*/
/*
//通过观察发现代码的重复度太高,所以用循环改进
for(int x=0; x<arr.length-1; x++){
for(int y=x+1; y<arr.length; y++){
if(arr[y] <arr[x]){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
System.out.println("排序后:");
printArray(arr);
*/
//用方法改进
selectSort(arr);
System.out.println("排序后:");
printArray(arr);
}
public static void selectSort(int[] arr){
for(int x=0; x<arr.length-1; x++){
for(int y=x+1; y<arr.length; y++){
if(arr[y] <arr[x]){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
// 遍历功能
public static void printArray(int[] arr) {
System.out.print("[");
for (int x = 0; x < arr.length; x++) {
if (x == arr.length - 1) {
System.out.print(arr[x]);
} else {
System.out.print(arr[x] + ", ");
}
}
System.out.println("]");
}
}
把字符串中的字符进行排序
举例:”dacgebf”
结果:”abcdefg”
package cn.it18zhang_03;
/*
* 把字符串中的字符进行排序。
* 举例:"dacgebf"
* 结果:"abcdefg"
*
* 分析:
* A:定义一个字符串
* B:把字符串转换为字符数组
* C:把字符数组进行排序
* D:把排序后的字符数组转成字符串
* E:输出最后的字符串
*/
public class ArrayTest {
public static void main(String[] args) {
// 定义一个字符串
String s = "dacgebf";
// 把字符串转换为字符数组
char[] chs = s.toCharArray();
// 把字符数组进行排序
bubbleSort(chs);
//把排序后的字符数组转成字符串
String result = String.valueOf(chs);
//输出最后的字符串
System.out.println("result:"+result);
}
// 冒泡排序
public static void bubbleSort(char[] chs) {
for (int x = 0; x < chs.length - 1; x++) {
for (int y = 0; y < chs.length - 1 - x; y++) {
if (chs[y] > chs[y + 1]) {
char temp = chs[y];
chs[y] = chs[y + 1];
chs[y + 1] = temp;
}
}
}
}
}
二分查找
package cn.it18zhang_04;
/*
* 查找:
* 基本查找:数组元素无序(从头找到尾)
* 二分查找(折半查找):数组元素有序
*
* 分析:
* A:定义最大索引,最小索引
* B:计算出中间索引
* C:拿中间索引的值和要查找的值进行比较
* 相等:就返回当前的中间索引
* 不相等:
* 大左边找
* 小右边找
* D:重新计算出中间索引
* 大左边找
* max = mid - 1;
* 小右边找
* min = mid + 1;
* E:回到B
*/
public class ArrayDemo {
public static void main(String[] args) {
//定义一个数组
int[] arr = {11,22,33,44,55,66,77};
//写功能实现
int index = getIndex(arr, 33);
System.out.println("index:"+index);
//假如这个元素不存在后有什么现象呢?
index = getIndex(arr, 333);
System.out.println("index:"+index);
}
/*
* 两个明确:
* 返回值类型:int
* 参数列表:int[] arr,int value
*/
public static int getIndex(int[] arr,int value){
//定义最大索引,最小索引
int max = arr.length -1;
int min = 0;
//计算出中间索引
int mid = (max +min)/2;
//拿中间索引的值和要查找的值进行比较
while(arr[mid] != value){
if(arr[mid]>value){
max = mid - 1;
}else if(arr[mid]<value){
min = mid + 1;
}
//加入判断
if(min > max){
return -1;
}
mid = (max +min)/2;
}
return mid;
}
}
Arrays类概述
针对数组进行操作的工具类。
提供了排序,查找等功能。
成员方法
public static String toString(int[] a)
public static void sort(int[] a)
public static int binarySearch(int[] a,int key)
package cn.it18zhang_05;
import java.util.Arrays;
/*
* Arrays:针对数组进行操作的工具类。比如说排序和查找。
* 1:public static String toString(int[] a) 把数组转成字符串
* 2:public static void sort(int[] a) 对数组进行排序
* 3:public static int binarySearch(int[] a,int key) 二分查找
*/
public class ArraysDemo {
public static void main(String[] args) {
// 定义一个数组
int[] arr = { 24, 69, 80, 57, 13 };
// public static String toString(int[] a) 把数组转成字符串
System.out.println("排序前:" + Arrays.toString(arr));
// public static void sort(int[] a) 对数组进行排序
Arrays.sort(arr);
System.out.println("排序后:" + Arrays.toString(arr));
// [13, 24, 57, 69, 80]
// public static int binarySearch(int[] a,int key) 二分查找
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 57));
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
}
}
源码分析
public static String toString(int[] a)
public static void sort(int[] a) 底层是快速排序,知道就可以了。有空看,有问题再问我
public static int binarySearch(int[] a,int key)
开发原则:
只要是对象,我们就要判断该对象是否为null。
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:" + Arrays.toString(arr));
public static String toString(int[] a) {
//a -- arr -- { 24, 69, 80, 57, 13 }
if (a == null)
return "null"; //说明数组对象不存在
int iMax = a.length - 1; //iMax=4;
if (iMax == -1)
return "[]"; //说明数组存在,但是没有元素。
StringBuilder b = new StringBuilder();
b.append('['); //"["
for (int i = 0; ; i++) {
b.append(a[i]); //"[24, 69, 80, 57, 13"
if (i == iMax)
//"[24, 69, 80, 57, 13]"
return b.append(']').toString();
b.append(", "); //"[24, 69, 80, 57, "
}
}
-----------------------------------------------------
int[] arr = {13, 24, 57, 69, 80};
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
public static int binarySearch(int[] a, int key) {
//a -- arr -- {13, 24, 57, 69, 80}
//key -- 577
return binarySearch0(a, 0, a.length, key);
}
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
int key) {
//a -- arr -- {13, 24, 57, 69, 80}
//fromIndex -- 0
//toIndex -- 5
//key -- 577
int low = fromIndex; //low=0
int high = toIndex - 1; //high=4
while (low <= high) {
int mid = (low + high) >>> 1; //mid=2,mid=3,mid=4
int midVal = a[mid]; //midVal=57,midVal=69,midVal=80
if (midVal < key)
low = mid + 1; //low=3,low=4,low=5
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
基本类型包装类概述
将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
常用的操作之一:用于基本数据类型与字符串之间的转换。
基本类型和包装类的对应
Byte,Short,Integer,Long,Float,Double
Character,Boolean
package cn.it18zhang_01;
/*
* 需求1:我要求大家把100这个数据的二进制,八进制,十六进制计算出来
* 需求2:我要求大家判断一个数据是否是int范围内的。
* 首先你的知道int的范围是多大?
*
* 为了对基本数据类型进行更多的操作,更方便的操作,Java就针对每一种基本数据类型提供了对应的类类型。包装类类型。
* byte Byte
* shortShort
* intInteger
* longLong
* floatFloat
* doubleDouble
* charCharacter
* booleanBoolean
*
* 用于基本数据类型与字符串之间的转换。
*/
public class IntegerDemo {
public static void main(String[] args) {
// 不麻烦的就来了
// public static String toBinaryString(int i)
System.out.println(Integer.toBinaryString(100));
// public static String toOctalString(int i)
System.out.println(Integer.toOctalString(100));
// public static String toHexString(int i)
System.out.println(Integer.toHexString(100));
// public static final int MAX_VALUE
System.out.println(Integer.MAX_VALUE);
// public static final int MIN_VALUE
System.out.println(Integer.MIN_VALUE);
}
}
Integer类概述及其构造方法
Integer类概述
Integer 类在对象中包装了一个基本类型 int 的值
该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法
构造方法
public Integer(int value)
public Integer(String s)
package cn.it18zhang_02;
/*
* Integer的构造方法:
* public Integer(int value)
* public Integer(String s)
* 注意:这个字符串必须是由数字字符组成
*/
public class IntegerDemo {
public static void main(String[] args) {
// 方式1
int i = 100;
Integer ii = new Integer(i);
System.out.println("ii:" + ii);
// 方式2
String s = "100";
// NumberFormatException
// String s = "abc";
Integer iii = new Integer(s);
System.out.println("iii:" + iii);
}
}
Integer类成员方法
int类型和String类型的相互转换
int – String
String – int
public int intValue()
public static int parseInt(String s)
public static String toString(int i)
public static Integer valueOf(int i)
public static Integer valueOf(String s)
package cn.it18zhang_03;
/*
* int类型和String类型的相互转换
*
* int -- String
* String.valueOf(number)
*
* String -- int
* Integer.parseInt(s)
*/
public class IntegerDemo {
public static void main(String[] args) {
// int -- String
int number = 100;
// 方式1
String s1 = "" + number;
System.out.println("s1:" + s1);
// 方式2
String s2 = String.valueOf(number);
System.out.println("s2:" + s2);
// 方式3
// int -- Integer -- String
Integer i = new Integer(number);
String s3 = i.toString();
System.out.println("s3:" + s3);
// 方式4
// public static String toString(int i)
String s4 = Integer.toString(number);
System.out.println("s4:" + s4);
System.out.println("-----------------");
// String -- int
String s = "100";
// 方式1
// String -- Integer -- int
Integer ii = new Integer(s);
// public int intValue()
int x = ii.intValue();
System.out.println("x:" + x);
//方式2
//public static int parseInt(String s)
int y = Integer.parseInt(s);
System.out.println("y:"+y);
}
}
Integer类成员方法
package cn.it18zhang_04;
/*
* 常用的基本进制转换
* public static String toBinaryString(int i)
* public static String toOctalString(int i)
* public static String toHexString(int i)
*
* 十进制到其他进制
* public static String toString(int i,int radix)
* 由这个我们也看到了进制的范围:2-36
* 为什么呢?0,...9,a...z
*
* 其他进制到十进制
* public static int parseInt(String s,int radix)
*/
public class IntegerDemo {
public static void main(String[] args) {
// 十进制到二进制,八进制,十六进制
System.out.println(Integer.toBinaryString(100));
System.out.println(Integer.toOctalString(100));
System.out.println(Integer.toHexString(100));
System.out.println("-------------------------");
// 十进制到其他进制
System.out.println(Integer.toString(100, 10));
System.out.println(Integer.toString(100, 2));
System.out.println(Integer.toString(100, 8));
System.out.println(Integer.toString(100, 16));
System.out.println(Integer.toString(100, 5));
System.out.println(Integer.toString(100, 7));
System.out.println(Integer.toString(100, -7));
System.out.println(Integer.toString(100, 70));
System.out.println(Integer.toString(100, 1));
System.out.println(Integer.toString(100, 17));
System.out.println(Integer.toString(100, 32));
System.out.println(Integer.toString(100, 37));
System.out.println(Integer.toString(100, 36));
System.out.println("-------------------------");
//其他进制到十进制
System.out.println(Integer.parseInt("100", 10));
System.out.println(Integer.parseInt("100", 2));
System.out.println(Integer.parseInt("100", 8));
System.out.println(Integer.parseInt("100", 16));
System.out.println(Integer.parseInt("100", 23));
//NumberFormatException
//System.out.println(Integer.parseInt("123", 2));
}
}
JDK5的新特性
JDK1.5以后,简化了定义方式。
Integer x = new Integer(4);可以直接写成
Integer x = 4;//自动装箱。
x = x + 5;//自动拆箱。通过intValue方法。
需要注意:
在使用时,Integer x = null;上面的代码就会出现NullPointerException。
package cn.it18zhang_05;
/*
* JDK5的新特性
* 自动装箱:把基本类型转换为包装类类型
* 自动拆箱:把包装类类型转换为基本类型
*
* 注意一个小问题:
* 在使用时,Integer x = null;代码就会出现NullPointerException。
* 建议先判断是否为null,然后再使用。
*/
public class IntegerDemo {
public static void main(String[] args) {
// 定义了一个int类型的包装类类型变量i
// Integer i = new Integer(100);
Integer ii = 100;
ii += 200;
System.out.println("ii:" + ii);
// 通过反编译后的代码
// Integer ii = Integer.valueOf(100); //自动装箱
// ii = Integer.valueOf(ii.intValue() + 200); //自动拆箱,再自动装箱
// System.out.println((new StringBuilder("ii:")).append(ii).toString());
Integer iii = null;
// NullPointerException
if (iii != null) {
iii += 1000;
System.out.println(iii);
}
}
}