1.数组常见操作
1.01数组高级冒泡排序
1.数组排序:把数组中的无序的元素,通过交换移动等方式,使数组中的元素,成为一个有序序列。
2.冒泡排序原理:
相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。
原理图:
3.分析以及代码实现:
规律:数组中有5个元素,比较了4轮。
第一轮:比较了4次。
第二轮:比较了3次。
第三轮:比较了2次。
第四轮:比较了1次。
public class MyTest {
public static void main(String[] args) {
int[] arr={24, 69, 80, 57, 13};
//因为arr[i+1],所以arr.length-1,要不然会越界。
for (int i = 0; i < arr.length-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length-1-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length-1-1-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length-1-1-1-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
}
}
public class MyTest {
public static void main(String[] args) {
int[] arr={24, 69, 80, 57, 13};
bubbleSort(arr);//抽取方法
//因为arr[i+1],所以arr.length-1,要不然会越界。
/* for (int j = 0; j<arr.length-1 ; j++) {
for (int i = 0; i< arr.length-1-j; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
*/
}
private static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length-1-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length-1-1-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length-1-1-1-1; i++) {
if(arr[i]>arr[i+1]){
int t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
System.out.println(Arrays.toString(arr));
}
}
//[24, 69, 57, 13, 80]
//[24, 57, 13, 69, 80]
//[24, 13, 57, 69, 80]
//[13, 24, 57, 69, 80]
1.02选择排序法
1.选择排序原理:
每次拿一个元素,跟后面剩余的元素,挨个比较,小的往前放,经过一轮比较后,最小的元素就会出现在最前面。
2.选择排序原理图:
3.分析以及代码实现:
选择排序的特点:
A:从0索引开始依次和后面的元素进行比较,小的往前放,第一次排序完毕以后,最小值出现在了最小索引处。
B:第一次比较的时候是从0索引开始比较了4次;
第二次比较的时候是从1索引开始比较了3次;
第三次比较的时候是从2索引开始比较了2次;
第四次比较的时候是从3索引开始比较了1次;
C:总共比较了4次;
public class MyTest {
public static void main(String[] args) {
int[] arr={24, 69, 80, 57, 13};
int index=0;
for (int i = 1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
System.out.println(Arrays.toString(arr));
index=1;
for (int i = 1+1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
System.out.println(Arrays.toString(arr));
index=2;
for (int i = 1+1+1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
System.out.println(Arrays.toString(arr));
index=3;
for (int i = 1+1+1+1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]=t;
}
}
System.out.println(Arrays.toString(arr));
}
}
public class MyTest {
public static void main(String[] args) {
int[] arr={24, 69, 80, 57, 13};
int index=0;
choicePaixu(arr, index); //抽取方法
/*for (index = 0; index <arr.length-1 ; index++) {
for (int i = 1+index; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
}
System.out.println(Arrays.toString(arr));*/
}
private static void choicePaixu(int[] arr, int index) {
for (int i = 1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
System.out.println(Arrays.toString(arr));
index=1;
for (int i = 1+1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
System.out.println(Arrays.toString(arr));
index=2;
for (int i = 1+1+1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]= t;
}
}
System.out.println(Arrays.toString(arr));
index=3;
for (int i = 1+1+1+1; i <arr.length ; i++) {
if(arr[index]>arr[i]){
int t=arr[index];
arr[index]=arr[i];
arr[i]=t;
}
}
System.out.println(Arrays.toString(arr));
}
}
1.03插入排序
直接插入排序:从第二个元素,每次拿一个后面元素插入之前的有序列中,使之仍保持有序
1.算法思路:直接插入排序,是一种最简单的排序方法.他的基本操作是将一个记录插入到一个长度为m 的有序表中,使之仍保持有序,从而得到一个新的长度为m+1的有序列表.假设有一组元素{k1,k2…,kn},排序开始就认为k1是一个有序序列,让k2插入上述表长为1的有序序列,使之成为一个表长为2的有序序列,然后让k3插入上述表长为2的有序序列,使之成为一个表长为3的有序序列,以此类推,最后让kn插入表长为n-1的有序序列,得到一个表长为n的有序序列。
•例如:
•49,38,65,97,76,13,27 原始数据
•[49],38,65,97,76,13,27 从1索引开始插入
•[38,49], ,65,97,76,13,27
•[38,49,65] 97,76,13,27
•[38,49,65,97] 76,13,27
•[38,49,65,76,97]13,27
•[13,27,38,49,65,76,97],27
•[13,27,38,49,65,76,97]
2.代码实现:
for while语句:
public static void main(String[] args) {
int[] arr={9,1,2,4,3,5,7,6,8,11,10,13,12};
//外层循环定义比较的轮次,也就是得几轮才能排序完
for (int i = 0; i < arr.length; i++) {
int j=i;
while(j>0&&arr[j]<arr[j-1]){//如果当前元素比前一个元素小交换位置
int t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;
j--;; //往前递减让当前元素继续和上一个元素比较
}
}
System.out.println(Arrays.toString(arr));
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
for for if语句:
public static void main(String[] args) {
int[] arr={9,1,2,4,3,5,7,6,8,11,10,13,12};
//外层循环定义比较的轮次,也就是得几轮才能排序完
for (int i = 0; i < arr.length; i++) {
for (int j = i; j >0 ; j--) {
if(arr[j]<arr[j-1]){
int t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;
}
}
}
System.out.println(Arrays.toString(arr));
}
1.04希尔排序
1.希尔排序原理:
希尔排序又称为缩小增量排序。是对插入排序的优化。也可以将插入排序认为增量为1的希尔排序。
基本思想:先将原表按增量ht分组,每个子文件按照直接插入排序。同样,用下一个增量
ht/2将文件再分为子文件,在直接插入法排序。直到ht=1时整个文件排好序。
关键:选择合适的增量。可以通过三重循环来实现。
2.原理图:
3.代码实现:
public static void main(String[] args) {
int[] arr={46,55,13,42,17,94,5,70};
//先把上节课讲的直接插入排序方法抽取出来
shellSort(arr);
}
private static void shellSort(int[] arr) {
//先复制一下之前插入排序的代码:
for (int i = 0; i < arr.length; i++) {
for (int j = i; j >0 ; j--) {
if(arr[j]<arr[j-1]){
*//*int t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;*//*
swapVlue(arr,i, j);
}
}
}
System.out.println(Arrays.toString(arr));
}
//将交换值的方法如下
private static void swapVlue(int[] arr,int i,int j){
int t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;
} //[5, 13, 17, 42, 46, 55, 70, 94]
public static void main(String[] args) {
int[] arr = {46, 55, 13, 42, 17, 94, 5, 70};
//先把上节课讲的直接插入排序方法抽取出来
shellSort(arr);
System.out.println(Arrays.toString(arr));
//[5, 13, 17, 42, 46, 55, 70, 94]
}
private static void shellSort(int[] arr) {
//定义一个增量
int h = 4;
for (int i = h; i < arr.length; i++) {
for (int j = i; j > h - 1; j -= h) {
if (arr[j] < arr[j - h]) {
int t = arr[j];
arr[j] = arr[j - h];
arr[j - h] = t;
}
}
}
//第二轮
h = 2;
for (int i = h; i < arr.length; i++) {
for (int j = i; j > h - 1; j -= h) {
if (arr[j] < arr[j - h]) {
int t = arr[j];
arr[j] = arr[j - h];
arr[j - h] = t;
}
}
}
h=1;
for (int i = h; i < arr.length; i++) {
for (int j = i; j > h - 1; j -= h) {
if (arr[j] < arr[j - h]) {
int t = arr[j];
arr[j] = arr[j - h];
arr[j - h] = t;
}
}
}
}
}
优化上面代码:
public static void main(String[] args) {
int[] arr = {46, 55, 13, 42, 17, 94, 5, 70};
//先把上节课讲的直接插入排序方法抽取出来
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void shellSort(int[] arr) {
for (int h = 4; h >0 ; h/=2) {
for (int i = h; i < arr.length; i++) {
for (int j = i; j > h - 1; j -= h) {
if (arr[j] < arr[j - h]) {
int t = arr[j];
arr[j] = arr[j - h];
arr[j - h] = t;
}
}
}
}
}
1.05快速排序法
1.分治法:比大小,再分区
从数组中取出一个数,作为基准数。
分区:将比这个数大或等于的数全放到他的右边,小于他的数全放到他的左边。
再对左右区间重复第二步,直到各区间只有一个数。
实现思路: 挖坑填数
将基准数挖出形成第一个坑。
由后向前找比他小的数,找到后挖出此数填到前一个坑中。
由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
再重复执行2,3两步骤。
2.代码实现:
public class QuickSrotUtils {
private QuickSrotUtils() {
}
public static void quickSrot(int[] arr, int start, int end) {
//递归调用左右两区
if (start < end) {
//获取分左右两区的那个位置索引
int index = getIndex(arr, start, end);
//对左区递归
quickSrot(arr, start, index - 1);
//对右区递归
quickSrot(arr, index + 1, end);
}
}
//挖坑填数:
/* 1.将基准数挖出形成第一个坑。
2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
4.再重复执行2,3两步骤。*/
private static int getIndex(int[] arr, int start, int end) {
int i = start;
int j = end;
//1.定义基准数
int x = arr[i];
//重复2 3 步
while (i < j) {
//2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
while (i < j && arr[j] >= x) {
j--;
}
if (i < j) {
arr[i] = arr[j];
i++;//顺便让i增一下
}
//3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
while (i < j && arr[i] < x) {
i++;
}
if (i < j) {
arr[j] = arr[i];
//顺便让j减一下
j--;
}
}
//把基准数,填到最后一个坑中
arr[i] = x;
return i;
}
}
public class MyTest {
public static void main(String[] args) {
int[] arr={20,20,6,8,9,1,2,3,4,90,100,3,0,-1,-2,6,9};
QuickSrotUtils.quickSrot(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
1.06二分法
1.原理:
二分查找:前提数组元素必须有序
二分查找的思想:每一次都查中间的那个元素,比较大小就能减少一半的元素。
2.原理图:
3.代码实现:
一般查找:
public class MyTest {
public static void main(String[] args) {
//查找该元素在数组中第一次出现的索引
//基本查找:从头开始挨个往找。
int[] arr = {10, 20, 30, 10, 50, 30, 90};
int index = getIndex(arr, 10);
System.out.println(index);
}
private static int getIndex(int[] arr, int ele) {
for (int i = 0; i < arr.length; i++) {
if (ele == arr[i]) {
return i;
}
}
return -1;
}
}
二分查找:
public class MyTest2 {
public static void main(String[] args) {
//查找该元素在数组中第一次出现的索引
//基本查找:从头开始挨个往找。
int[] arr = {10, 20, 30, 40, 50, 60, 90};
//int index = getIndex(arr, 90);
//二分查找的前提:数组元素有序。
int index = getIndex2(arr, 40);
System.out.println(index);
}
//二分查找
private static int getIndex2(int[] arr, int ele) {
//定义最小索引和最大索引
int minIndex = 0;
int maxIndex = arr.length - 1;
int centerIndex = (minIndex + maxIndex) / 2;
while (minIndex <= maxIndex) {
if (ele == arr[centerIndex]) {
return centerIndex;
} else if (ele < arr[centerIndex]) {
maxIndex = centerIndex - 1;
} else if (ele > arr[centerIndex]) {
minIndex = centerIndex + 1;
}
//记得再次计算中间索引
centerIndex = (minIndex + maxIndex) / 2;
}
return -1;
}
2.Arrays
2.1Arrays类概述
针对数组进行操作的工具类。提供了排序,查找等功能
2.成员方法
public static String toString(int[] a)
public class MyTest {
public static void main(String[] args) {
//Java给我们提供了一个工具类,可以方便的对数组进行操作。
int[] arr={10,20,30};//[10,20,30]
//toString(arr);把数组中的元素,转换成一个漂亮字符串。
String s = Arrays.toString(arr);
System.out.println(s);
}
}
public static void sort(int[] a)
public static int binarySearch(int[] a,int key)
public static void main(String[] args) {
int[] arr = {20, 20, 6, 8, 9, 1, 2, 3, 4, 90, 100, 3, 0, -1, -2, 6, 9};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//[-2, -1, 0, 1, 2, 3, 3, 4, 6, 6, 8, 9, 9, 20, 20, 90, 100]
//二分查找:数组元素必须有序
int index = Arrays.binarySearch(arr, 100);
System.out.println(index);//16
static boolean equals(int[] a, int[] a2) 比较两个数组中的元素,是否一样
public static void main(String[] args) {
int[] arr = {20, 20, 6, 8};
int[] arr2 = {20, 20, 6, 8};
//比较两个数组中的元素是否一样。
boolean b = Arrays.equals(arr, arr2);
System.out.println(b);
}
static int[] copyOf(int[] original, int newLength) 复制旧数组中的元素到一个新的数组
中,新的数组长度是newLength 从0开始复制旧数组
static int[] copyOfRange(int[] original, int from, int to) 复制旧数组中的指定范围间的几个元素到新数组中。
public static void main(String[] args) {
/* static int[] copyOf ( int[] original, int newLength)复制旧数组中的元素到一个新的数组中,新的数组长度是newLength 从0开始复制旧数组
static int[] copyOfRange ( int[] original, int from, int to)复制旧数组中的指定范围间的几个元素到新数组中*/
int[] arr = {20, 20, 6, 8,20,30,50,60};
int[] ints = Arrays.copyOf(arr, 3);
System.out.println(Arrays.toString(ints));
//3 起始索引,6 终止索引 含头不含尾
int[] ints1 = Arrays.copyOfRange(arr, 3, 6);
System.out.println(Arrays.toString(ints1));
}