各种排序算法

本文详细介绍了四种基础排序算法:插入排序、选择排序、冒泡排序和快速排序。插入排序通过比较元素并移动找到其正确位置;选择排序每次找到最小元素放到已排序区;冒泡排序通过反复交换相邻元素实现排序;快速排序则采用分治策略,通过一趟排序确定基准元素位置。每种算法都有其适用场景和效率特点。
摘要由CSDN通过智能技术生成

插入排序

插入排序(InsertionSort),一般也被称为直接插入排序。
对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表
在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

第一轮:从第二位置的 6 开始比较,比前面 7 小,交换位置。

在这里插入图片描述

第二轮:第三位置的 9 比前一位置的 7 大,无需交换位置。

在这里插入图片描述

第三轮:第四位置的 3 比前一位置的 9 小交换位置,依次往前比较。

在这里插入图片描述

第四轮:第五位置的 1 比前一位置的 9 小,交换位置,再依次往前比较。

在这里插入图片描述

  public static void InsertSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                if (arr[j] < arr[j - 1]) {
                    int tmp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = tmp;
                } else
                    break;
            }
        }
    }

选择排序

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理是这样的:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中
继续寻找最小(大)元素,然后放到已排序系列的末尾。依次类推,直到所有全是均排序完毕。

选择排序主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序
每次交换一对元素,它们当中至少有一个将被移动到其他最终位置上,因此,对n个元素的表进行排序总共
进行至多n-1此交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。

在这里插入图片描述

从这个图来看,选择排序实际上把列表分成了左右的两部分,左边是已经排序好的部分,右边是没有排序的数列。第一次,13是最小,位置不用移动,第二次从13之外剩余数列中选择一个最小的数是27,然后把27拿出来,放到13的后面。依次类推,左边已经排序好的越来越多,右边未排序的越来越少,直到右边没有元素

   public static void slectSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int MinIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[MinIndex] > arr[j]) {
                    MinIndex = j;
                }
            }
            int tmp = arr[i];
            arr[i] = arr[MinIndex];
            arr[MinIndex] = tmp;
        }
    }

冒泡排序

冒泡排序(Bubble
Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

冒泡排序的过程和图解分析

冒泡排序算法的运作如下:
1)比较相邻的元素,如果第一个比第二个大(升序),就交换他们两个位置。
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完,最后的元素会是最大的数。
3)针对所有的元素重复以上步骤,除了最后一个。
4)持续每次对越来越少的元素重复上面步骤,直到没有任何一对数字需要比较。

下面这个图,表示第一个步骤和第二个步骤的过程。
在这里插入图片描述

上面一遍走下来之后,确保最大的数字93已经排到最末尾了,下次就排序93之前的数据就可以。依次,第二次走完一遍,数字77会放到93的前面,也就是整个数列倒数第二个位置。以此类推,每下一次要排序的数列都会缩短一个元素,需要交换的次数也越来越小,直到不需要交换位置,这个时候排序结束。

   private static void BubbleSort(int[] arr) {
        int tmp;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                }
            }
        }
    }

快速排序

快速排序(QuickSort),又称划分交换排序,通过一趟排序将要排序的数据分割成独立的两部分。其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按照此方法对两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序思想和图解

快速排序步骤为:
1.从数列中挑出一个元素,称为"基准"。
2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准大的摆放在基准的后面,相同的可以摆到任意一边。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是0或者1,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次迭代中,它至少会把一个元素摆放到它最后面的位置去。
在这里插入图片描述

package com.anthony.sort;
 
import java.util.Arrays;
 
public class QuickSort {
	public static void main(String[] args) {
		int[] arr = {54, 26, 93, 17, 77, 31, 44, 55, 20};
		System.out.println(Arrays.toString(arr));
		quickSort(arr, 0, arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	
	public static void quickSort(int[] arr, int first, int last) {
		if (first >= last){
			return ;
		}
		int mid_value =  arr[first];
		int low = first;
	    int high = last;
		    while ( low < high) {
			    // 基准值和high对应值比较,high左移
		        while ( low < high && arr[high] >= mid_value) {
		            // 说明high对应元素大于中间基准值,high需要往左移动
		            high -= 1;
		        }
		        // 退出循环,把high和low对应元素进行位置交换
		        int tmp = arr[low];
		        arr[low] = arr[high];
		        arr[high] = tmp;
		        // 基准值和low对应的值比较, low右移
		        while ( low < high && arr[low] < mid_value) {
		            low += 1;
		        }
		        // 退出循环,
		        int tmp1 = arr[high];
		        arr[high] = arr[low];
		        arr[low] = tmp1;
		    }
		    // 从循环退出时,low==high
		    arr[low] = mid_value;
 
		    // 对low左边列表执行快速排序,递归调用
		    quickSort(arr, first, low-1);
		    // 对low右边列表进行排序
		    quickSort(arr, low+1, last);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值