一、冒泡排序
两两比较,找到最大值或者最小值的方式
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个,即需要进行length-1次。
第一次是对n个数进行n-1次比较,进行到最后第n个的一个是最大的;
第二次是对n-1个数进行n-2次比较,进行到最后第n-1个的一个是最大的;
…
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
对10个同学的成绩按照从低到高的顺序排列
package d715;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
double temp=0;
double[] scores = new double[10];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.print("请输入第"+ (i+1) +"个同学的成绩:");
scores[i] = sc.nextDouble();
}
int i,j;
for(i=0;i<scores.length-1;i++) {
for(j=0;j<scores.length-1-i;j++) {
if(scores[j]>scores[j+1]) {
swap(scores,j,j+1);
}
}
}
for(int k=0;k<scores.length;k++) {
System.out.print(scores[k]+" ");}
}
private static void swap(double[] score, int j, int i) {
score[j]=score[j]+score[i];
score[i]=score[j]-score[i];
score[j]=score[j]-score[i];
}
}
二、选择排序
每次找到最小值,将它交换到对应的位置(第一位)
选择排序算法的原理如下:
1.从0索引开始,依次和后面元素比较,如果0索引的元素小则不变,反之,交换他们的值。第一次完毕,最小值出现在了0索引处;
2.从1索引开始,重复1步骤,第二小的值出现在了1索引处;
3.针对所有的元素重复以上的步骤,除了最后一个。
对10个同学的成绩按照从低到高的顺序排列
package d715;
import java.util.Scanner;
public class Test4 {
public static void main(String[] args) {
double temp;
double[] scores = new double[10];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.print("请输入第"+ (i+1) +"个同学的成绩:");
scores[i] = sc.nextDouble();
}
for(int i=0;i<scores.length;i++) {
int min=i;
for(int j=i;j<scores.length;j++) {
if(scores[min]>scores[j]) {
min=j;
}
}
if(min!=i) {
temp=scores[i];
scores[i]=scores[min];
scores[min]=temp;
}
System.out.print(scores[i]+" ");
}
}
}
三、插入排序
默认第一个是有序的,第二个开始,向有序进行插入
每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。
插入排序,顾名思义其基本操作就是插入,不断把一个个元素插入到一个序列中,最终得到排序序列。
步骤:
1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果被扫描的元素(已排序)大于新元素,将该元素后移一位
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5.将新元素插入到该位置后
6.重复步骤2~5
对10个同学的成绩按照从低到高的顺序排列
package d715;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
double temp=0;
double[] scores = new double[10];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.print("请输入第"+ (i+1) +"个同学的成绩:");
scores[i] = sc.nextDouble();
}
Sort(scores);
for(double i:scores) {
System.out.print(i+" ");
}
}
private static void Sort(double[] scores) {
for (int i = 1; i <scores.length; i++) {
for (int j = i; j >0 && scores[j] < scores[j - 1] ; j--) {
swap(scores, j, j - 1);
}
}
}
private static void swap(double[] scores, int j, int i) {
scores[j]=scores[j]+scores[i];
scores[i]=scores[j]-scores[i];
scores[j]=scores[j]-scores[i];
}
}
四、二分查找(折半查找)
二分查找是一种查询效率非常高的查找算法。又称折半查找。
有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。
将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
package com.openlab.day08.sort;
public class TestSearch {
public static void main(String[] args) {
int[] arr = {1, 2, 9, -100, -55, 23, -99, 0, 3, 4, 8};
TestSort.bubbleSort(arr);
// int index = linearSearch(arr, 23);
int index = binarySearch(arr, -999);
System.out.println(index);
}
// 线性查找,可以查询,但是效率较低,随着数据越来越多
public static int linearSearch(int[] arr, int key) {
for (int i = 0; i < arr.length; i++) {
if (key == arr[i]) {
return i;
}
}
return -1;
}
// 二分查找,又被叫做折半查找
public static int binarySearch(int[] arr, int key) {
int start = 0;
int end = arr.length - 1;
while (start <= end) {
// 注意,需要将中间值的下标重新计算
int middle = (start + end) / 2;
if (arr[middle] > key) {
end = middle - 1;
} else if (arr[middle] < key) {
start = middle + 1;
} else {
return middle;
}
}
return -1;
}
}