排序算法总结

插入排序

直接插入排序

在这里插入图片描述

直接插入排序:将待排序的元素插入到前面已经排序好的序列中

折半插入排序

在这里插入图片描述

当 low>high 时折半查找停⽌,应将 [low, i-1] 内的元素全部右移,并将 A[0] 复制到 low 所指位置
在这里插入图片描述

在这里插入图片描述

希尔排序(内部使用:直接插入)

在这里插入图片描述

在这里插入图片描述

交换排序

冒泡排序

在这里插入图片描述

从后往前(或从前往后)两两⽐较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列⽐较完。称这样过程为“⼀趟”冒泡排序。
在这里插入图片描述

快速排序

在这里插入图片描述
在这里插入图片描述

package sort;

import java.util.Arrays;

public class Test6
{

	public static void main(String[] args)
	{
		int[]arr= {-9,78,30,0,23,-567,70};
		quickSort(arr, 0, arr.length-1);
		System.out.println("arr="+Arrays.toString(arr));
	}
	public static void quickSort(int[] arr, int left, int right)
	{
		int l = left; //左下标
		int r = right; //右下标
		//pivot 中轴值
		int pivot = arr[(left + right) / 2];
		int temp = 0; //临时变量,作为交换时使用
		//while循环的目的是让比pivot 值小放到左边
		//比pivot 值大放到右边
		while (l < r)
		{
			//在pivot的左边一直找,找到大于等于pivot值,才退出
			while (arr[l] < pivot)
			{
				l += 1;
			}
			//在pivot的右边一直找,找到小于等于pivot值,才退出
			while (arr[r] > pivot)
			{
				r -= 1;
			}
			//如果l >= r说明pivot 的左右两的值,已经按照左边全部是
			//小于等于pivot值,右边全部是大于等于pivot值
			if (l >= r)
			{
				break;
			}

			//交换
			temp = arr[l];
			arr[l] = arr[r];
			arr[r] = temp;

			//如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
			if (arr[l] == pivot)
			{
				r -= 1;
			}
			//如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
			if (arr[r] == pivot)
			{
				l += 1;
			}
		}

		// 如果 l == r, 必须l++, r--, 否则为出现栈溢出
		if (l == r)
		{
			l += 1;
			r -= 1;
		}
		//向左递归
		if (left < r)
		{
			quickSort(arr, left, r);
		}
		//向右递归
		if (right > l)
		{
			quickSort(arr, l, right);
		}
	}
}



package sort;

import java.util.Arrays;

public class Test6_1
{
	public static void main(String[] args)
	{
		//给出无序数组
		int arr[] =
		{
				72, 6, 57, 88, 60, 42, 83, 73, 48, 85
		};

		//输出无序数组
		System.out.println(Arrays.toString(arr));
		//快速排序
		quickSort(arr);
		//partition(arr,0,arr.length-1);
		//输出有序数组
		System.out.println(Arrays.toString(arr));
	}

	public static void quickSort(int[] arr)
	{
		int low = 0;
		int high = arr.length - 1;
		quickSort(arr, low, high);
	}

	private static int partition(int[] arr, int low, int high)
	{
		//指定左指针i和右指针j
		int i = low;
		int j = high;

		//将第一个数作为基准值。挖坑
		int x = arr[low];

		//使用循环实现分区操作
		while (i < j)
		{//5  8
			//1.从右向左移动j,找到第一个小于基准值的值 arr[j]
			while (arr[j] >= x && i < j)
			{
				j--;
			}
			//2.将右侧找到小于基准数的值加入到左边的(坑)位置, 左指针想中间移动一个位置i++
			if (i < j)
			{
				arr[i] = arr[j];
				i++;
			}
			//3.从左向右移动i,找到第一个大于等于基准值的值 arr[i]
			while (arr[i] < x && i < j)
			{
				i++;
			}
			//4.将左侧找到的打印等于基准值的值加入到右边的坑中,右指针向中间移动一个位置 j--
			if (i < j)
			{
				arr[j] = arr[i];
				j--;
			}
		}

		//使用基准值填坑,这就是基准值的最终位置
		arr[i] = x;//arr[j] = y;
		//返回基准值的位置索引
		return i; //return j;
	}

	private static void quickSort(int[] arr, int low, int high)
	{//???递归何时结束
		if (low < high)
		{
			//分区操作,将一个数组分成两个分区,返回分区界限索引
			int index = partition(arr, low, high);
			//对左分区进行快排
			quickSort(arr, low, index - 1);
			//对右分区进行快排
			quickSort(arr, index + 1, high);
		}

	}

}


在这里插入图片描述
在这里插入图片描述

  1. 最好情况:每趟快速排序选择的枢轴元素划分很均匀——排序趟数O(log 2 n)
  2. 每趟可确定多个元素的最终位置
    在这里插入图片描述

选择排序

简单选择排序

每⼀趟在待排序元素中选取关键字最⼩的元素加⼊有序⼦序列
加入的方法是:这个最小元素与第一个待排序元素交换位置
n个元素的简单选择排序需要 n-1 趟处理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

堆排序

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

堆排序的插入与删除

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二路归并排序(外部排序)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最好最坏的比较次数

问:将有序数组 归并排序 最多与最少比较次数

设有两个有序数组 arr1 与 arr2,数组长度分别为 m 与 n, 要合并成一个长度位 m+n 的有序数组 arr3.

最差情况下:比较次数为 m+n-1
此时,将数组 arr1 与数组 arr2 中的元素两两比较,将值小的放进数组 arr3, 直到数组 arr3 填满为止。
因为 arr3 有 m+n 个空位,每次两两比较就放进去一个数,而最后一个剩下的元素可以不用比较直接放进去,所以一共两两比较了 m+n-1 次。

最好情况下:比较次数为 min{m, n}
一定要注意,这是简单归并排序,必须从第一个元素比。
因此,最好情况下,至少需要两两比较一个数组的长度,比较次数为 min{m,n}

基数排序

在这里插入图片描述
在这里插入图片描述

算法复杂度总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

外部排序(m哈夫曼树)

在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sparky*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值