常用的排序算法有冒泡排序、插入排序、选择排序、快速排序、堆排序、归并排序、希尔排序、二叉树排序、计数排序等。
1.冒泡法排序算法
基本原理:冒泡排序是一种简单的排序算法。它重复地比较相邻的元素,并根据大小交换它们的位置,使得每次迭代都能将最大(或最小)的元素冒泡到数组的一端,从而实现排序。
算法原理图:
源程序(举例):
package swp.kaifamiao.codes.Java.d0808;
import java.util.Arrays;
/**
* {class description}
*
* @author SWP
* @version 1.0.0
*/
//冒泡排序
public class Demo03 {
public static void main(String[] args) {
//定义一个数组
int[] arr = {5, 1, 2, 4, 9, 3};
for (int j =0;j<arr.length-1;j++){
//内循环,遍历数组中所有的数并让其两两作比较,让较大的数往后放,此时定义的i为下标,用来遍历数组中所有的数
for (int i=0;i<arr.length-1-j; i++){
if (arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
2.选择排序算法
基本原理:每次从未排序的部分中选择最小(或最大)的元素,然后将其放到已排序部分的最后。通过重复这个过程,直到所有元素都排序完成。
算法原理图:
源程序(举例):
package swp.kaifamiao.codes.Java.d0808;
import java.util.Arrays;
/**
* {class description}
*
* @author SWP
* @version 1.0.0
*/
// 选择排序,找到最值放到相应的位置
public class Demo02 {
public static void main(String[] args) {
int[] arr = {2, 9, 4, 5, 6, 1};
for (int i =0;i<arr.length-1;i++){
//最小值的下标
int min = i;
for (int j=i+1; j<arr.length; j++){
if (arr[j] < arr[min]){
min = j;
}
}
//交换位置
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
System.out.println(Arrays.toString(arr));
}
}
3.插入排序算法
基本思想:将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素,插入到已排序部分的合适位置,直至全部元素都被插入到已排序部分,完成排序。
算法原理图:
源程序(举例):
package swp.kaifamiao.codes.Java.d0808;
import java.util.Arrays;
/**
* {class description}
*
* @author SWP
* @version 1.0.0
*/
//插入排序
public class Demo04 {
public static void main(String[] args) {
int[] arr = {3, 5, 2, 8, 9, 6};
//遍历数组中每一个元素,假设第一个数就是最大的,所以i只需要从1开始
for (int i = 1; i <arr.length; i++){
//定义当前值
int current = arr[i];
//定义前一个元素的下标
int preIndex = i - 1;
while (preIndex >=0 && arr[preIndex] > current){
//如果说前一个元素的值要大于当前元素的值,则让前一个元素后移一位
arr[preIndex + 1] = arr[preIndex];
preIndex --;
}
//当前值的位置
arr[preIndex + 1] = current;
}
System.out.println(Arrays.toString(arr));
}
}
拓展:二分法查找数组元素
二分查找(Binary Search)是一种高效的查找算法,用于在已排序的数组中查找指定的元素。以下是二分查找的步骤:
(1) 确定查找范围:将待查找的数组的开始和结束位置确定为左右两个指针,初始时左指针指向数组的第一个元素,右指针指向数组的最后一个元素。
(2) 计算中间位置:通过将左右指针相加并除以2,可以得到当前查找区域的中间位置。
(3) 比较目标值:将目标值与中间位置的元素进行比较。如果目标值等于中间位置的元素,则找到了该元素,查找结束。如果目标值小于中间位置的元素,则说明目标值在左半部分,将右指针移动为中间位置的前一个位置。如果目标值大于中间位置的元素,则说明目标值在右半部分,将左指针移动为中间位置的后一个位置。
(4) 更新查找范围:根据比较结果更新左右指针的位置,缩小查找范围。
(5) 重复步骤2至步骤4,直到找到目标值或左指针大于右指针,表示查找失败。
二分查找与选择查找的区别:
package swp.kaifamiao.codes.Java.d0809;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
import java.util.Scanner;
/**
* {class description}
*
* @author SWP
* @version 1.0.0
*/
//二分查找数组元素
public class Demo04 {
public static void main(String[] args) {
// 定义一个整数数组
int[] arr = {2, 5, 7, 8, 9 ,11, 13};
// 使用Scanner类从控制台获取用户输入的数并进行定义
Scanner in = new Scanner(System.in);
System.out.println("请输入查找的数:");
int num = in.nextInt();
// 定义左右下标
int left = 0;
int right = arr.length - 1;
// 初始化查找结果为-1
int result = -1;
//循环判断控制台输入的数和数组中间下标的数作比较,遍历
while (left <= right) {
int middle = (left + right) >> 1;
if (arr[middle] > num) {
right = middle - 1;
} else if (arr[middle] < num) {
left = middle + 1;
} else {
// 更新查找结果
result = middle;
// 找到目标数,跳出循环
break;
}
}
if (left > right) {
System.out.println("目标数不存在于数组中");
} else {
System.out.println("目标数在数组中的索引为:" + result);
}
}
}