冒泡排序
冒泡排序的思想:
将元素之间两两进行比较,如果前一个数字比后一个数字大,那么这两个数字交换位置,到最后,最大的数字就被换到了最后面。 逐步分解:
int [ ] arr = { 3 , 9 , - 1 , 10 , - 2 } ;
int temp = 0 ;
for ( int i = 0 ; i < arr. length - 1 ; i++ ) {
if ( arr[ i] > arr[ i + 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i + 1 ] ;
arr[ i + 1 ] = temp;
}
}
System. out. println ( "第一次比较完之后的数组为:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
for ( int i = 0 ; i < arr. length - 2 ; i++ ) {
if ( arr[ i] > arr[ i + 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i + 1 ] ;
arr[ i + 1 ] = temp;
}
}
System. out. println ( "第二次比较完之后的数组为:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
for ( int i = 0 ; i < arr. length - 3 ; i++ ) {
if ( arr[ i] > arr[ i + 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i + 1 ] ;
arr[ i + 1 ] = temp;
}
}
System. out. println ( "第三次比较完之后的数组为:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
for ( int i = 0 ; i < arr. length - 4 ; i++ ) {
if ( arr[ i] > arr[ i + 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i + 1 ] ;
arr[ i + 1 ] = temp;
}
}
System. out. println ( "第四次比较完之后的数组为:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
int temp = 0 ;
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 ] ) {
temp = arr[ j] ;
arr[ j] = arr[ j + 1 ] ;
arr[ j + 1 ] = temp;
}
}
}
冒泡排序的时间复杂度分析:使用了两层循环,所以时间复杂度是O(n^2)。下面使用容量为80000的数组来测试该程序的运行时间
int [ ] arr = new int [ 80000 ] ;
for ( int i = 0 ; i < arr. length; i++ ) {
arr[ i] = ( int ) ( Math. random ( ) * 80000 ) ;
}
public static void sortTime ( int [ ] arr) {
Date date = new Date ( ) ;
SimpleDateFormat dateFormat = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) ;
String format1 = dateFormat. format ( date) ;
System. out. println ( "排序前的时间:" + format1) ;
int temp = 0 ;
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 ] ) {
temp = arr[ j] ;
arr[ j] = arr[ j + 1 ] ;
arr[ j + 1 ] = temp;
}
}
}
Date date2 = new Date ( ) ;
String format2 = dateFormat. format ( date2) ;
System. out. println ( "排序后的时间:" + format2) ;
排序前的时间: 2020 - 03 - 16 09 : 41 : 06
排序后的时间: 2020 - 03 - 16 09 : 41 : 25
选择排序
选择排序的思想:
从0索引处的元素和后面的元素一一进行比较,如果后者比其小,则交换位置 逐步分解:
int [ ] arr = { 101 , 34 , 119 , 1 } ;
int minIndex = 0 ;
int min = arr[ 0 ] ;
for ( int i = 0 + 1 ; i < arr. length; i++ ) {
if ( arr[ 0 ] > arr[ i] ) {
minIndex = i;
min = arr[ i] ;
}
}
arr[ minIndex] = arr[ 0 ] ;
arr[ 0 ] = min;
System. out. println ( "第一轮之后数组" + Arrays. toString ( arr) ) ;
minIndex = 1 ;
min = arr[ 1 ] ;
for ( int i = 1 + 1 ; i < arr. length; i++ ) {
if ( arr[ 1 ] > arr[ i] ) {
minIndex = i;
min = arr[ i] ;
}
}
arr[ minIndex] = arr[ 1 ] ;
arr[ 1 ] = min;
System. out. println ( "第二轮之后数组" + Arrays. toString ( arr) ) ;
minIndex = 2 ;
min = arr[ 2 ] ;
for ( int i = 2 + 1 ; i < arr. length; i++ ) {
if ( arr[ 2 ] > arr[ i] ) {
minIndex = i;
min = arr[ i] ;
}
}
arr[ minIndex] = arr[ 2 ] ;
arr[ 2 ] = min;
System. out. println ( "第三轮之后数组" + Arrays. toString ( arr) ) ;
for ( int i = 0 ; i < arr. length - 1 ; i++ ) {
int minIndex = i;
int min = arr[ minIndex] ;
for ( int j = i + 1 ; j < arr. length; j++ ) {
if ( min > arr[ j] ) {
minIndex = j;
min = arr[ j] ;
}
}
arr[ minIndex] = arr[ i] ;
arr[ i] = min;
}
选择排序的时间复杂度分析:使用了两层循环,所以时间复杂度是O(n^2)。下面使用容量为80000的数组来测试该程序的运行时间
int [ ] arr = new int [ 80000 ] ;
for ( int i = 0 ; i < arr. length; i++ ) {
arr[ i] = ( int ) ( Math. random ( ) * 80000 ) ;
}
Date date = new Date ( ) ;
SimpleDateFormat dateFormat = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) ;
String format1 = dateFormat. format ( date) ;
System. out. println ( "排序前的时间:" + format1) ;
sort ( arr) ;
Date date2 = new Date ( ) ;
String format2 = dateFormat. format ( date2) ;
System. out. println ( "排序后的时间:" + format2) ;
排序前的时间: 2020 - 03 - 16 09 : 45 : 28
排序后的时间: 2020 - 03 - 16 09 : 45 : 32
希尔排序
希尔排序的思想:
希尔排序就是设置一个增量,然后每次排序将增量减半,其实就是对选择排序的优化 演示:
import java.util.Arrays;
public class XiEr {
public static void main(String[] args) {
int []arr={24,14,33,2,51,19};
//希尔排序的思想:选取一个增量,然后每次排序将增量减半,其实就是对插入排序的优化,只不过插入排序的增量为1
for (int h = arr.length/2; 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 temp = arr[j];
arr[j] = arr[j - h];
arr[j - h] = temp;
}
}
}
}
System.out.println(Arrays.toString(arr));
}
}
插入排序
插入排序的思想:
把索引为1的元素作为一个参考值,如果后面的元素比它小,则把该元素放在它之前 -逐步分解:
int temp = 0 ;
for ( int i = 1 ; i > 0 ; i-- ) {
if ( arr[ i] < arr[ i - 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i - 1 ] ;
arr[ i - 1 ] = temp;
}
}
System. out. println ( "第一轮结束后:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
for ( int i = 2 ; i > 0 ; i-- ) {
if ( arr[ i] < arr[ i - 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i - 1 ] ;
arr[ i - 1 ] = temp;
}
}
System. out. println ( "第二轮结束后:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
for ( int i = 3 ; i > 0 ; i-- ) {
if ( arr[ i] < arr[ i - 1 ] ) {
temp = arr[ i] ;
arr[ i] = arr[ i - 1 ] ;
arr[ i - 1 ] = temp;
}
}
System. out. println ( "第三轮结束后:" ) ;
System. out. println ( Arrays. toString ( arr) ) ;
for ( int i = 1 ; i < arr. length; i++ ) {
for ( int j = i; j > 0 ; j-- ) {
if ( arr[ j] < arr[ j - 1 ] ) {
temp = arr[ j] ;
arr[ j] = arr[ j - 1 ] ;
arr[ j - 1 ] = temp;
}
}
}
插入排序的时间复杂度分析:使用了两层循环,所以时间复杂度是O(n^2)。下面使用容量为80000的数组来测试该程序的运行时间
int [ ] arr = new int [ 80000 ] ;
for ( int i = 0 ; i < arr. length; i++ ) {
arr[ i] = ( int ) ( Math. random ( ) * 80000 ) ;
}
Date date = new Date ( ) ;
SimpleDateFormat dateFormat = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) ;
dateFormat. format ( date) ;
System. out. println ( "排序前时间" + date) ;
sortBetter ( arr) ;
Date date2 = new Date ( ) ;
SimpleDateFormat dateFormat2 = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) ;
dateFormat2. format ( date2) ;
System. out. println ( "排序后时间" + date2) ;
快速排序
快速排序的思想:
设置一个参考值,比参考值大的放在其右边,比参考值小的放左边 演示:
import java.util.Arrays;
public class QuickSortDemo {
public static void main(String[] args) {
int[] arr = {24, 69,69, 80, 57, 13};
quicksort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
public static void quicksort(int[] arr, int left, int right) {
if (left > right) {//如果左边的索引超过了右边的索引,则方法结束
return;
}
int key = arr[left];
int i = left;
int j = right;
while (i != j) {
while (arr[j] >= arr[left] && j > i) {//j索引所在的值比参考值大,且j大于i
j--;//j向前挪
}
while (arr[i] <= arr[left] && i < j) {//i索引所在的值比参考值小,且i<j
i++;//i向后挪
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//跳出while循环即i和j相遇了,此时要把i里面的值给参考坐标里面,再把参考值给i
arr[left] = arr[i];
arr[i] = key;
//对左边的元素再进行以上操作
quicksort(arr, left, i - 1);
//对右边的元素再进行以上操作
quicksort(arr, j + 1, right);
}
}
二分查找
二分查找的思想:
把要找的值每次和数组的中间值进行比较,如果比中间值小,则中间值右边的值丢弃,如果比中间值大,则把中间值左边的值丢弃,以此类推 演示:
import java.util.Scanner;
public class ErFen {
public static void main(String[] args) {
int []arr={1,3,5,7,9,10};
//先用中间的和用户输入num进行判断,如果num<mid,则最大值应该往左挪,如果num》mid,最小值应该往右挪
System.out.println("输入数字");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int min=0;
int max=arr.length-1;
int mid=(min+max)/2;
int index;
while (min<=max){
if (num==arr[mid]){
index=mid;
System.out.println(index);
break;
}else if(num<arr[mid]){
max=mid-1;
}else if(num>arr[mid]){
min=mid+1;
}
mid=(min+max)/2;
}
}
}