数据结构及算法之排序
业精于勤,荒于嬉;行成于思,毁于随。——韩愈
最近有学习几个排序算法,记录下来以便之后用到。这里主要讲四个算法:选择排序、冒泡排序、插入排序
、快速排序。
选择排序
选择排序通俗的讲就是每次从数组中找出最小值与第一个位置交换,如此往复。选择排序是:不稳定排序、时间复杂度是O(n²),废话不多说直接上图演示。
演示图
我们列出一个数组int[] arr = {22,7,10,1,5,24,6,23}
java代码实现
public class Sort {
private static int[] arr = {22,7,10,1,5,24,6,23};
public static void main(String[] args) {
//减1是为了在嵌套循环中,j=i+1防止索引越界
for (int i = 0; i < arr.length - 1; i++) {
//最小的标记,外层循环一次,内容循环一圈
int min = i;
for (int j = i + 1; j < arr.length; j++) {
//如果有小于的最小标记值的,将最小标记的索引替换为j
if (arr[min] > arr[j]) {
min = j;
}
}
//如果内层循环一圈走完并且min!=i进行交换,这一趟走完找到第一个最小值,接着执行下一次
if(min!=i){
int temp;
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+",");
}
}
}
执行结果
冒泡排序
冒泡排序通俗的讲就是每次循环找到最大值放到数组的最左边去,时间复杂度为:O(n²),是稳定排序。
我们列出一个数组int[] arr = {22,7,10,1,5,24,6,23}
演示图
经历四趟以后排序已经完成,但是根据外层循环程序还是会执行8次
java代码实现
public class Sort {
private static int[] arr = {22,7,10,1,5,24,6,23};
public static void main(String[] args) {
for (int i = 0; i < arr.length; i++) {
//这里arr.length-1是为了防止索引越界,减i是去除每次排好序的元素
for (int j = 0; j < arr.length - 1-i; j++) {
//每次拿两个相邻元素做比较,并判断交换与否
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+",");
}
}
}
执行结果
直接插入排序
直接插入排序是以第一个元素为基,遍历数组剩余元素与基准元素对比放入排好序数组的指定位置。直接插入排序为:时间复杂度为O(n²),是稳定排序
我们列出一个数组int[] arr = {22,7,10,1,5,24,6,23}
演示图
代码演示
public class Sort {
private static int[] arr = {22,7,10,1,5,24,6,23};
public static void main(String[] args) {
//这里i从1开始,是因为while循环里面要arr[j]与arr[j-1]比
for (int i = 1; i < arr.length; i++) {
int j = i;
while (j>0){
if(arr[j]<arr[j-1]){
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1]=temp;
j--;
}else{
//如果要比较的树与已经排好序的数组的最后一个数还大,那就break
break;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+",");
}
}
}
执行结果
快速排序
快速排序和冒泡排序一样属于交换排序的一种,定义一个基准元素,一般定义数组的一个元素。定义元素开始位置为low,结束位置为high,先从最后面开始遍历找到小于等于基准元素的数填入数组的第一个坑中,再从数组前往后找,找到第一个大于基准元素的与填入一个坑的元素互换位置,以此类推。快速排序的时间复杂度为:O(nlog2n),是不稳定排序。
演示图
代码演示
public class Sort {
private static int[] arr = {22, 7, 10, 1, 5, 24, 6, 23};
public static void main(String[] args) {
//默认low为0,high为arr.length - 1
quickSort(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
private static void quickSort(int[] arr, int low, int high) {
//low<high才循环
if (low < high) {
//获取每次排序的中间索引
int mid = getMidIndex(arr, low, high);
//在分批次遍历索引左侧的数组
quickSort(arr, 0, mid - 1);
//遍历索引右侧的数组
quickSort(arr, mid + 1, high);
}
}
private static int getMidIndex(int[] arr, int low, int high) {
//定义基准值
int temp = arr[low];
//low<high才循环
while (low < high) {
//从后往前找小于基准值的数
while (low<high&&arr[high]>=temp){
high--;
}
arr[low] = arr[high];
//从前往后找大于基准值的数
while (low<high&&arr[low]<=temp){
low++;
}
arr[high] = arr[low];
}
arr[low] = temp;
//此时low就是中间索引值
return low;
}
}