1.冒泡排序
(1)冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
(2) 算法描述:比较相邻的元素。如果第一个比第二个大,就交换它们两个;对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;针对所有的元素重复以上的步骤,除了最后一个;重复步骤1~3,直到排序完成。
(3)流程图解释:
(4)程序代码解释
package Chapter02;
import java.util.Arrays;
public class Demo03 { public static void main(String[] args) {
int[] array = {10,5,3,7,6};
myBubblesort(array);
System.out.println(Arrays.toString(array));
}
public static void myBubblesort(int[] array) {
//外层循环
for (int i = 0; i < array.length; i++) {
//内层循环
for (int j = 0; j < array.length - 1; j++) {
//两个值相互比较
if (array[j] > array[j + 1]) {
int tmp = 0;
//两个值进行交换
tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
}
}
}
}
2,选择排序
(1)选择排序(Selection-sort)是一种简单直观的排序算法,是表现最稳定的排序算法之一,因为无论什么数据进去都是O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间。
(2)算法描述:初始状态下,原序列是无序的,有序的序列为空。第一次遍历,找到最小的数字,与当前序列的第一位交换,第一位即归为有序序列。其后为无序序列。第二次遍历,从第二位数字(即无序序列)开始遍历,找到最小的数字,与无序序列的第一位交换,前两个数字即为有序序列,其后为无序序列。依次反复直至结束。
其中大括号内为无序区,大括号外为有序序列:
初始序列:{49 27 65 97 76 12 38}
第1轮:12与49交换:12{27 65 97 76 49 38}
第2轮:27不动 :12 27{65 97 76 49 38}
第3轮:65与38交换:12 27 38{97 76 49 65}
第4轮:97与49交换:12 27 38 49{76 97 65}
第5轮:76与65交换:12 27 38 49 65{97 76}
第6轮:97与76交换:12 27 38 49 65 76 97 完成
(4)程序设计
package Chapter02;
//导入Arrays的方法
import java.util.Arrays;//Arrays因为不是默认加载的类,所以要在代码中使用import语句引入才可以使用
import java.util.Random;
public class Demo02 {
public static void main(String[] args) {
Random random =new Random();//创建一个随机类对象
int[] a =new int[10];//创建一个int型的数组,长度为10;
//大前提或逻辑运算,防止数组为null或者数组里面只有一个元素无法进行比较
if (a == null || a.length <= 1) {
return;
}
//遍历数组
for(int i =0; i < a.length; i++) {
a[i] = random.nextInt(100);//随机生成一个0-100的随机数,生成10个,然后将这10个数存入创建的数组中
}
//输出随机生成的数组
System.out.println(Arrays.toString(a));
//下面是选择排序的程序(从小到大)
//外部循环
for(int i =0; i < a.length -1; i++){
int min = a[i];//设第一个元素为最小值
int index = i;//这里是记录最小值的下标
//内部循环
//内循环控制每一轮被比较的元素因为第一个元素为最小值,从第二个元素开始跟第一个元素比较
for(int j = i +1; j < a.length; j++){
if(min > a[j]){
min = a[j];
index = j;//这里把最小值的数组下标给index
}
}
//交换元素
int t = a[i];
a[i] = a[index];
a[index] = t;
}
//输出排序后的数组
System.out.println(Arrays.toString(a));
}
}
[5, 92, 85, 44, 7, 37, 58, 12, 84, 67]
[5, 7, 12, 37, 44, 58, 67, 84, 85, 92]
3. 插入排序
(1)插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
(2)算法描述:一般来说,插入排序都采用in-place在数组上实现,从第一个元素开始,该元素可以认为已经被排序;取出下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置;重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;将新元素插入到该位置后;重复步骤2~5。
(3)程序设计
package Chapter02;
import java.util.Arrays;
public class Demo03 { public static void main(String[] args) {
int[] numbers = {5,3,2,6,4};
System.out.println("排序前的结果为:" + Arrays.toString(numbers));
for (int i = 1; i < numbers.length; i++) { //控制循环轮数
int temp = numbers[i]; //定义待交换元素
int j; //定义待插入的位置
for (j = i; j > 0 && temp < numbers[j - 1]; j --) {
numbers[j] = numbers[j - 1];
}
numbers[j] = temp;
System.out.println("第" + i + "轮的排序结果为:" + Arrays.toString(numbers));
}
System.out.println("排序后的结果为:" + Arrays.toString(numbers));
}
}
4,快速排序
(1)快排作为最常用的排序算法,主要是以一个数为基准数,将数组中的其他数按一定的顺序放入两边。以从小到大排序为例,快排的操作就是将比基准数小的都放到它的左边,比基准数大的都放到它的右边,然后左右两边再分别重复这个操作,不停地分,直至分到每一个分区的基准数的左边或者右边都只剩一个数为止。这时这组数组的排序也就完成了。主要采用的是分治的思想。
(2)算法描述从数列中挑出一个元素,称为 “基准”(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
(3)程序设计
package Chapter02;
import java.util.Arrays;
public class Demo03 { public static void main(String[] args) {
int[] array = {99, 78, 30, 9, 47, 88, 36, 29, 27, 4, 46, 4, 19, 56, 48};
// 只需要修改成对应的方法名就可以了
quickSort(array);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] array) {
quickSort(array, 0, array.length - 1);
}
private static void quickSort(int[] array, int left, int right) {
if (array == null || left >= right || array.length <= 1) {
return;
}
int mid = partition(array, left, right);
quickSort(array, left, mid);
quickSort(array, mid + 1, right);
}
private static int partition(int[] array, int left, int right) {
int temp = array[left];
while (right > left) {
// 先判断基准数和后面的数依次比较
while (temp <= array[right] && left < right) {
--right;
}
// 当基准数大于了 arr[left],则填坑
if (left < right) {
array[left] = array[right];
++left;
}
// 现在是 arr[right] 需要填坑了
while (temp >= array[left] && left < right) {
++left;
}
if (left < right) {
array[right] = array[left];
--right;
}
}
array[left] = temp;
return left;
}
}