为自己学习所用,将自己掌握的排序算法整理成思路记录下来
1、选择排序(正序)
思路:
选择排序是所有排序里边比较简单的,至少我这么认为,它的大致思路是每次都找到数组中的最小(最大)下标,然后将arr[i]
的值与最小下标的值互换。
1、定义一个变量存储index_min
最小值的下标,
2、使用两层for
循环,外层for
循环控制遍历整个数组,内部数组寻找最小值
3、在内部循环中,将外层循环的i
的值赋值给index_min
,将第一个值arr[index_min]
假定为最小值,并使用内层循环寻找最小值的下标,并将值赋值给index_min
,
4、找到最小值下标后,将最小值与第一个元素互换位置
代码实现:
//使用自定义工具类生成指定长度的数组
int[] arr = DesignateRandom_Utils.random_Int(6, 20, 30) ;
//遍历数组
DesignateRandom_Utils.traversal(arr);
/*
这两个为自建工具类,可使用第一个创建一个指定长度的一维数组
第二个为对数组遍历
*/
public static void Sort_Insertion() {
//使用自定义工具类生成指定长度的数组
int[] arr = DesignateRandom_Utils.random_Int(6, 20, 30) ;
//遍历数组
DesignateRandom_Utils.traversal(arr);
//开始遍历数组
for (int i = 0; i < arr.length; i++) {
//定义最小值下标,
int index_min = i ;
//循环遍历i + 1 后面的值,如果最小值下标对应的元素大于后面的值
//则将后面值的索引赋值给index_min
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[index_min]) {
index_min = j ;
}
}
//当i对应的值与index_min相等,则没有交换的必要
if (arr[i] > arr[index_min]) {
int temp = arr[i] ;
arr[i] = arr[index_min] ;
arr[index_min] = temp ;
}
}
//输出
for (int i : arr) {
System.out.print(i + " ");
}
}
2、冒泡排序(正序)
思路:
1、定义指向数组第一个位置和第二个位置的指针(实际就是下标或者值)
2、当相邻两个元素左值大于右值时,两元素交换位置,则可以得出每发生一次完整的数组遍历,都会找到该数组的最大值或最小值
3、使用两层for
循环,内层循环做1,2两件事,外层数组控制整个数组的遍历
4、内层交换次数最多为arr.length - 1
,每进行一次都能找到相对极值,所以外层最多遍历arr.length - 1
次。
优化:
5、由于数组并非完全无序,可在交换值里边定义一个计数器,当完成一次(趟)交换,判断计数器的值,当计数器(exit_loop
)为零时,可认为上一趟未发生元素交换,直接使用break
跳出循环
代码实现:
简单版
public static int[] Sort_Bubble_simple(int[] arr) {
System.out.println("排序前");
for (int i : arr) {
System.out.print(i + " ");
}
// 排序
for (int i = 0; i < arr.length; i++) {
// 内层排序,j = i
for (int j = i; j < arr.length; j++) {
// 定义指针,指向数组的第一个值
int num = arr[i];
// 判断,交换值
if (num > arr[j]) {
int num_temp = arr[i];
arr[i] = arr[j];
arr[j] = num_temp;
}
}
}
System.out.println("\n-------");
System.out.println("排序后");
for (int i : arr) {
System.out.print(i + " ");
}
return arr;
}
优化版
public static int[] Sort_Bubble(int[] arr) {
System.out.println("---------------------BubbleSTART---------------------");
// 排序前输出
System.out.println("冒泡排序前:");
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println("\n排序过程:");
// 排序,递增排序,只要前一个数比后一个数大,就交换其位置
for (int i = 0; i <= arr.length - 1; i++) {
// 定义指针,外循环每循环一次,指针置零
int pointer = 0;
// 当没有发生交换时,for循环退出
int exit_loop = 0;
// 进行交换
for (int j = i + 1; j <= arr.length - 1; j++) {
// 交换
if (arr[pointer] > arr[pointer + 1]) {
int num_temp = arr[pointer];
arr[pointer] = arr[pointer + 1];
arr[pointer + 1] = num_temp;
exit_loop += 1;
}
//指针右移
pointer += 1;
}
// 判断本轮是否发生了交换,不发生,直接退出
if (exit_loop == 0) {
break;
}
System.out.print("第" + (i + 1) + "次排序,结果是:");
for (int j : arr) {
System.out.print(j + " ");
}
System.out.println();
}
// 排序后输出
System.out.println("冒泡排序后:");
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println("\n---------------------BubbleEND---------------------");
return arr;
}
3、插入排序(正序)
思路:
1、选择排序是将数组的第一个值看做有序部分,然后获取第二个值(key = arr[1])与第一个值比较
2、如果第二个值大于第一个值,则将第一个值赋值给第二个值,第二个值赋值给第一个
3、对于第三个或者之后的值,将第三个值或者之后的值取出(目标值)
4、目标值循环与前一个值比较,并将前一个值赋值给目标值所在的位置,目标值找到位置,
5、进行下一次循环
代码实现:
public static int[] Sort_Insertion(int[] arr) {
// 代码
// 排序
for (int i = 1; i < arr.length; i++) {
// 取第一个元素
int key = arr[i];
// 定义比较次数,与元素位置有关
int j = i - 1;
// 比较,当第一个元素大于第二个元素,就把第一个元素赋值给第二个
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
// j自减,再与前一个值比较
j -= 1;
}
// 比较完成,再把key的值赋值给j + 1的位置
arr[j + 1] = key;
}
for (int i : arr) {
System.out.print(i + " ");
}
return arr;
}