我们在学习java的过程中,肯定会遇到过很多的排序算法,今天我们就来讲讲常用的排序中的:插入排序,选择排序,冒泡排序以及快速排序吧!
一、插入排序
(一)插入排序的原理
我从网上找到的图片:
插入算法其实我是这么理解的:
将数组中的数从左往右依次取出,然后用取出的数和它左边的数进行比较,如果取出的数大于它左边的数就互换位置,一直循环,直到取出的这个数的左边的数比它小或者到达数组的最左边才结束循环,不再互换。
(二)插入排序的实现
/**
* 插入算法
*将数组中的数从左往右依次取出,然后用取出的数和它左边的数进行比较,
* 如果取出的数大于它左边的数就互换位置,一直循环,
* 直到取出的这个数的左边的数比它小或者到达数组的最左边才结束循环,不再互换,
* 进入下一个数的循环。
*/
public static void InsertionSort(int[] arrs){
//从左往右依次取出arrs中数组的一个数
for (int i = 0 ; i < arrs.length ; i ++){
//设置一个temp帮助交换
int temp;
//依次取出i左边的所有数
for (int j = i ; j > 0 ; j --){
//只要num比这个数小就交换
if(arrs[j] < arrs[j-1]){
temp = arrs[j-1];
arrs[j-1] = arrs[j];
arrs[j] = temp;
}else{
//遇到比num小的数,我们就可以不用再循环了,后面的数都比num小
break;
}
}
}
System.out.print("插入排序结果: ");
for (int i = 0 ; i < arrs.length ; i ++){
System.out.print(arrs[i] + " ");
}
}
public static void main(String[] args) {
int[] arrs = {15,45,10,6,81,54,71};
InsertionSort(arrs);
}
结果:
二、选择排序
(一)选择排序原理
网上的图片:
选择排序我的理解是这样:
其实简单选择排序很简单,就是遍历数组选择一个最小的数放第一位,然后把第一位之后的所有数当成一个新的数组再遍历选出最小的放在这个新数组的第一位,一直循环,直至最后只剩一位数。
(二)选择排序实现
/**
*其实简单选择排序很简单,就是遍历数组选择一个最小的数放第一位,
* 然后把第一位之后的所有数当成一个新的数组再遍历选出最小的放在这个新数组的第一位,
* 一直循环,直至最后只剩一位数。
*/
public static void SelectionSort(int[] arrs){
for (int i = 0 ; i < arrs.length ; i ++){
for (int j = i + 1 ; j < arrs.length ; j ++) {
if (arrs[i] < arrs[j]) {
int temp = arrs[j];
arrs[j] = arrs[i];
arrs[j] = temp;
}
}
}
System.out.print("选择排序结果: ");
for (int i = 0 ; i < arrs.length ; i ++){
System.out.print(arrs[i] + " ");
}
}
public static void main(String[] args) {
int[] arrs = {15,45,10,6,81,54,71,1};
SelectionSort(arrs);
}
结果:
三、冒泡排序
(一)冒泡排序原理:
先看网图:
我的理解是这样:
一轮冒泡排序的流程包含数组元素个数次循环,每次循环都从左往右依次取一个数,并把取出的数A和它右边的数B进行比较,如果A>B就交换两个数的位置,然后一直循环到取出的数右边没有数为止,一轮结束。循环轮数为数组元素个数。
(二)冒泡排序的实现
/**
* 一轮冒泡排序的流程包含数组元素个数次循环,
* 每次循环都从左往右依次取一个数,
* 并把取出的数A和它右边的数B进行比较,
* 如果A>B就交换两个数的位置,
* 然后一直循环到取出的数右边没有数为止,
* 一轮结束。
* 循环轮数为数组元素个数。
* @param arrs
*/
public static void bubbleSort(int[] arrs){
//循环次数等于数组元素个数
for (int i = 0 ; i < arrs.length ; i++){
//设置一个状态判断这次循环中是否有交换,如果全程没有交换,就证明已经排序好了,可以跳出循环了
int changeState = 0;
for (int j = 0 ; j < arrs.length-1 ; j++){
if(arrs[j] > arrs[j+1]){
int temp = arrs[j];
arrs[j] = arrs[j+1];
arrs[j+1] = temp;
changeState = 1;
}
}
if(changeState == 0){
System.out.println("现在是第"+ i +"次,排序完了跳出循环");
break;
}
}
System.out.print("冒泡排序结果: ");
for (int i = 0 ; i < arrs.length ; i ++){
System.out.print(arrs[i] + " ");
}
}
public static void main(String[] args) {
int[] arrs = {15,45,10,6,81,54,71,1};
// InsertionSort(arrs);
// SelectionSort(arrs);
bubbleSort(arrs);
}
结果:
四、快速排序(好东西)
(一)快速排序原理
说下我对整个流程理解:
假设我们有这么一个数组:
①首先我们需要取一个值做为比较值,比如选中数组最左边的值,然后就把最左边的元素选中(找个变量存着),把这个元素的位置设置为空值(用于后面新的值的交换)。
②然后我们有两个指针,分别指向最左边和最右边,左边的指针负责找比choice选中的比较值大的数丢到右边去,右边的指针负责找比choice选中的比较值小的数丢到左边去。
③指针J先开始移动,然后它指向了1,判断出1比choice的值15小,所以要放在15的左边,所以,将1放到指针i所在的位置
④右边指针j完成交换后,要轮到左边指针i进行移动,指针i向右移动指向45,判断45>choice,所以要将45放到指针j所在位置,也就是比较值的右边:
⑤然后指针i结束,轮到指针j向左移动,指向71,71>choice不移动,54>choice不移动,81>choice不移动,直到指向6,6<choice,将6移到指针i所在位置:
⑥指针j移动结束,轮到指针i向右移动,10<choice 不移动,然后直到指向指针j所指向的位置,发生第一次接触碰头,然后我们就可以看到i和j所指向的位置的左边都是比choice小的数,右边都是比choice大的数,所以现在i和j共同所指向的位置便是第一次执行完后choice的值15所在的位置。
⑦然后choice的左边和右边看成是两个子数组,分别重复上述步骤:
然后最终就能得到:
所以这就是我理解的整个快速排序的流程!
(二)代码实现:
public static class QuickSort {
public static void sort(int arr[], int low, int high) {
int l = low;
int h = high;
int povit = arr[low];
while (l < h) {
while (l < h && arr[h] >= povit)
h--;
if (l < h) {
arr[l] = arr[h];
l++;
}
while (l < h && arr[l] <= povit)
l++;
if (l < h) {
arr[h] = arr[l];
h--;
}
}
arr[l] = povit;
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.print("l=" + (l + 1) + "h=" + (h + 1) + "povit=" + povit + "\n");
if (l - 1 > low)
sort(arr, low, l - 1);
if (h + 1 < high)
sort(arr, h + 1, high);
}
}
public static void main(String[] args) {
int[] arr = {15,45,10,6,81,54,71,1 };
int low = 0;
//不至于为什么-1都要我说吧 arr[arr.length]你看看你越不越界
int high = arr.length-1;
QuickSort.sort(arr, low, high);
}
好的,时间有限今天就写到这吧,万分感谢!