13.Java-数组高级冒泡排序、高级选择排序、直接插入排序、快速排序、基数排序、二分查找
一、数组高级冒泡排序原理图解
A:画图演示
需求:
数组元素:{24, 69, 80, 57, 13}
请对数组元素进行排序。
B:冒泡排序原理
相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
二、数组高级冒泡排序代码实现
package org.westos.java12;
public class Test8 {
public static void main(String[] args) {
int[] arr={24,69,80,57,13};
for (int i = arr.length-1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if(arr[j]>=arr[j+1]){
int t=arr[j];
arr[j]=arr[j+1];
arr[j+1]=t;
}
}
}
String s="[";
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
s+=arr[i]+"]";
}else{
s+=arr[i]+",";
}
}
System.out.println(s);
}
}
package org.westos.java12;
public class Test8 {
public static void main(String[] args) {
int[] arr={24,69,80,57,13};
for (int i = arr.length-1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if(arr[j]<=arr[j+1]){
int t=arr[j];
arr[j]=arr[j+1];
arr[j+1]=t;
}
}
}
String s="[";
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
s+=arr[i]+"]";
}else{
s+=arr[i]+",";
}
}
System.out.println(s);
}
}
package org.westos.java12;
import java.util.Arrays;
public class Test8 {
public static void main(String[] args) {
int[] arr={24,69,80,57,13};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1-i; j++) {
if(arr[j]>=arr[j+1]){
int t=arr[j+1];
arr[j+1]=arr[j];
arr[j]=t;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
三、数组高级选择排序原理图解
A:画图演示
需求:
数组元素:{24, 69, 80, 57, 13}
请对数组元素进行排序。
B:选择排序原理
从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
package org.westos.java15;
import java.util.Arrays;
public class XuZe {
public static void main(String[] args) {
int[] arr={24,69,80,80,57,13};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i]>arr[j]){
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
四、直接插入排序
package org.westos.java15;
import java.util.Arrays;
public class ZhiJieChaRu {
public static void main(String[] args) {
int[] arr={9,1,2,8,5,45,45,6,9};
for (int i = 1; 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));
}
}
package org.westos.java15;
import java.util.Arrays;
public class ZhiJieChaRu2 {
public static void main(String[] args) {
int[] arr={9,1,2,8,5,45,45,6,9};
for (int i = 1; i < arr.length; i++) {
int j=i;
while(j>0&&arr[j]<arr[j-1]){
swapValue(arr,j,j-1);
j--;
}
}
System.out.println(Arrays.toString(arr));
}
public static void swapValue(int[] arr,int index1,int index2){
int t=arr[index1];
arr[index1]=arr[index2];
arr[index2]=t;
}
}
五、快速排序
分治法:比大小,再分区
1.从数组中取出一个数,作为基准数。
2.分区:将比这个数大或等于的数全放到他的右边,小于他的数
全放到他的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
挖坑填数
1.将基准数挖出形成第一个坑。
2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
4.再重复执行2,3两步骤。
例如对 5391672408 进行排序
package org.westos.java16;
public class QuickSortTest {
public static void quickSort(int[] arr,int start,int end){
if(start<end){
int index=getindex(arr,start,end);
quickSort(arr,start,index-1);
quickSort(arr,index+1,end);
}
}
private static int getindex(int[] arr, int start, int end) {
int i=start;
int j=end;
int x=arr[i];
while(i<j){
while(i<j&&arr[j]>=x){
j--;
}
if(i<j){
arr[i]=arr[j];
i++;
}
while(i<j&&arr[i]<x){
i++;
}
if(i<j){
arr[j]=arr[i];
j--;
}
}
arr[i]=x;
return i;
}
}
package org.westos.java16;
public class QuickSortTest {
public static void quickSort(int[] arr,int start,int end){
if(start<end){
int index=getindex(arr,start,end);
quickSort(arr,start,index-1);
quickSort(arr,index+1,end);
}
}
private static int getindex(int[] arr, int start, int end) {
int i=start;
int j=end;
int x=arr[i];
while(i<j){
while(i<j&&arr[j]<x){
j--;
}
if(i<j){
arr[i]=arr[j];
i++;
}
while(i<j&&arr[i]>=x){
i++;
}
if(i<j){
arr[j]=arr[i];
j--;
}
}
arr[i]=x;
return i;
}
}
package org.westos.java16;
import java.util.Arrays;
public class Test9 {
public static void main(String[] args) {
int[] arr={1,20,5,1,4,8,9,20,2,50,9};
QuickSortTest.quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
六、基数排序
基数排序不同于之前所介绍的各类排序
前边介绍到的排序方法或多或少的是通过使用比较和移动记录来实现排序
而基数排序的实现不需要进行对关键字的比较
只需要对关键字进行“分配”与“收集”两种操作即可完成。
package org.westos.java16;
import java.util.Arrays;
public class Test10 {
public static void main(String[] args) {
int[] arr={1,25,5,89,6,54,21,3,2,0};
sortArr(arr);
System.out.println(Arrays.toString(arr));
}
private static void sortArr(int[] arr) {
int[][] sum=new int[10][arr.length];
int[] counts=new int[10];
int max=getmax(arr);
int length = String.valueOf(max).length();
for (int i = 0,n=1; i < length; i++,n*=10) {
for (int j = 0; j < arr.length; j++) {
int ys=arr[j]/n%10;
sum[ys][counts[ys]++]=arr[j];
}
int index=0;
for (int k = 0; k < counts.length; k++) {
if(counts[k]!=0){
for (int u = 0; u < counts[k]; u++) {
arr[index]=sum[k][u];
index++;
}
counts[k]=0;
}
}
}
}
private static int getmax(int[] arr) {
int max=arr[0];
for (int i = 0; i < arr.length; i++) {
if(arr[i]>max){
max=arr[i];
}
}
return max;
}
}
package org.westos.java16;
import java.util.Arrays;
public class Test10 {
public static void main(String[] args) {
int[] arr={1,25,5,89,6,54,21,3,2,0};
sortArr(arr);
System.out.println(Arrays.toString(arr));
}
private static void sortArr(int[] arr) {
int[][] sum=new int[10][arr.length];
int[] counts=new int[10];
int max=getmax(arr);
int length = String.valueOf(max).length();
for (int i = 0,n=1; i < length; i++,n*=10) {
for (int j = 0; j < arr.length; j++) {
int ys=arr[j]/n%10;
sum[ys][counts[ys]++]=arr[j];
}
if(i==length-1){
int index=arr.length-1;
for (int k = 0; k < counts.length; k++) {
if(counts[k]!=0){
for (int u = 0; u < counts[k]; u++) {
arr[index]=sum[k][u];
index--;
}
counts[k]=0;
}
}
break;
}
int index=0;
for (int k = 0; k < counts.length; k++) {
if(counts[k]!=0){
for (int u = 0; u < counts[k]; u++) {
arr[index]=sum[k][u];
index++;
}
counts[k]=0;
}
}
}
}
private static int getmax(int[] arr) {
int max=arr[0];
for (int i = 0; i < arr.length; i++) {
if(arr[i]>max){
max=arr[i];
}
}
return max;
}
}
七、二分查找
A:画图演示
B:二分查找:前提数组元素必须有序
C:二分查找的思想:每一次都查中间索引的那个元素,比较大小就能减少一半的元素。
注意:二分查找不是找该元素第一次出现的索引。
比如下面这个数组,找4元素的索引,找出来的索引是5
int[] arr = {1,2,3,4,4,4,6,7,8,9,10};
基本查询:从头开始挨个往后找,该元素第一次出现的索引。
package org.westos.java16;
import java.util.Arrays;
public class Test11 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,4,4,6,7,8,9,10};
System.out.println(sortBinary(arr, 10));
System.out.println(sortBinary(arr, 4));
System.out.println(Arrays.binarySearch(arr, 8));
int i = binarySearch0(arr, 0, arr.length, 7);
System.out.println(i);
}
public static int sortBinary(int[] arr,int num){
int start=0;
int end=arr.length-1;
while(start<=end){
int mid=(start+end)/2;
if(arr[mid]==num){
return mid;
}else if(arr[mid]>num){
end=mid-1;
}else{
start=mid+1;
}
}
return -1;
}
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
int key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid;
}
return -(low + 1);
}
}
八、改进版二分查找
package org.westos.java16;
import java.util.Arrays;
public class Test29 {
public static void main(String[] args) {
int[] arr={1,2,2,2,6,7,8,9};
int i = Arrays.binarySearch(arr, 2);
System.out.println(i);
System.out.println(searchBinary(arr, 2));
}
public static int searchBinary(int[] arr,int num){
int start=0;
int end=arr.length-1;
while(start<=end){
int mid=(start+end)>>1;
if(arr[mid]>num){
end=mid-1;
}else if(arr[mid]<num){
start=mid+1;
}else{
while(mid>0&&arr[mid-1]==arr[mid]){
mid--;
}
return mid;
}
}
return -(start+1);
}
}
package org.westos.java16;
public class Test31 {
public static void main(String[] args) {
int[] arr={9,8,8,8,6,5,5,5,4,3,2};
System.out.println(searchBinary2(arr, 5));
}
public static int searchBinary2(int[] arr,int num){
int start=0;
int end=arr.length-1;
while(start<=end){
int mid=(start+end)>>1;
if(arr[mid]>num){
start=mid+1;
}else if(arr[mid]<num){
end=mid-1;
}else{
while(mid>0&&arr[mid-1]==arr[mid]){
mid--;
}
return mid;
}
}
return -(start+1);
}
}