Java数据结构——直接插入排序+希尔排序+冒泡排序

一、插入排序

(一)、什么是插入排序

  • 插入排序 ( InsertionSort ),一般也被称为直接插入排序
  • 函数命名:insertionSort
  • 原理
1. 将一个记录插入到“已经排好序”的有序表中。
2. 从而形成一个新的、数据项增 1 的“有序表”。
  • 算法
1. 两个for循环
2. 外层循环:对除了第一个元素之外的所有元素
3. 内层循环:对当前元素前面有序表进行待插入位置查找,并进行移动
  • 性能分析
1. 时间复杂度 O(n^2)
2. 空间复杂度 O(1)
3. 当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较 N-14. 最坏的情况是待排序数组是逆序的,此时需要比较次数最多,最坏的情况是 O(n^2)

(二)、图例


在这里插入图片描述

  • 监视哨的目的:避免数组下标出界

(三)、Java代码

  • insertionSort
	/**
	 * 直接插入排序
	 * 
	 * @param arrs 待排序数组
	 */
	public void insertionSort(int[] arrs) {
		int n = arrs.length;

		for (int i = 0; i < n; i++) {
			// 1. 寻找元素 arrs[i] 合适的插入位置
			for (int j = i; j > 0; j--) {
				// 2. 找到合适位置就交换
				if (arrs[j] < arrs[j - 1]) // 决定升降序
					swap(arrs, j, j - 1);
				else
					break;
			}
		}
	} // insertionSort
  • swap
	/**
	 * 数组两个位置交换
	 * 
	 * @param arrs
	 * @param i
	 * @param j
	 */
	private void swap(int[] arrs, int i, int j) {
		int temp = arrs[i];
		arrs[i] = arrs[j];
		arrs[j] = temp;
	} // swap
  • testOfInsertionSort
	public static void testOfInsertionSort() {
		int[] arrs = { 5, 11, 1, 0, -1, 15, 20, 100, -99 };
		Sort sort = new Sort();

		sort.insertionSort(arrs);
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]);
			System.out.print(" ");
		}
	}
  • 输出样例
直接插入排序:
-99 -1 0 1 5 11 15 20 100 

二、希尔排序

(一)、什么是希尔排序

  • 希尔排序,也称递减增量排序算法。
  • 希尔排序比直接插入排序更高效:直接插入排序每次只能将数据移动一位
  • 希尔排序是非稳定排序算法简单形式化一下,如果Ai = Aj,Ai原来在位置前,排序后Ai还是要在Aj位置前,这是排序的稳定性
  • 原理
1. 先将整个待排序的序列分割成为若干子序列。
2. 对子序列分别进行直接插入排序。
3. 待每个子序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
  • 算法
1. 确定一个增量k
2. 对序列进行 k 趟排序
3. 每趟排序,看情况交不交换(升降)
4. 仅增量因子为 1 时,排序完成
  • 性能
1. 时间复杂度:O(n^1.5)

(二)、图例


在这里插入图片描述

  • 第一趟:增量为5
  • 第二趟:增量为3
  • … …
  • 直到增量为1

(三)、Java代码

-shellSort

	/**
	 * 希尔排序
	 * 
	 * @param arrs
	 */
	public void shellSort(int[] arrs) {
		int n = arrs.length;
		
		// 1. 以n/2为间隔(增量),直到增量为1
		for (int step = n / 2; step >= 1; step /= 2) {
			
			// 2. 直接插入排序
			for (int i = step; i < n; i++) {
				// j每次递减是减少step那么多
				for(int j=i; j>step-1; j-=step) {
					if(arrs[j-step] > arrs[j])
						swap(arrs, j-step, j);
					else
						break;
				}
			}
		}
	} // shellSort
  • testOfShellSort
	/**
	 * 测试希尔排序
	 */
	public static void testOfShellSort() {
		int[] arrs = { 5, 11, 1, 0, -1, 15, 20, 100, -99 };
		Sort sort = new Sort();

		sort.shellSort(arrs);
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]);
			System.out.print(" ");
		}
	}
  • 输出样例
希尔排序:
-99 -1 0 1 5 11 15 20 100 

三、冒泡排序

(一)、什么是冒泡排序

  • 这个用的最多,又简单,主要是原理。
  • 简单了解一下原理。
  • 算法简单。
  • 冒泡排序(Bubble Sort)
  • 这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
  • 算法
1. 比较相邻的元素。如果第一个比第二个大,就交换。
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3. 针对所有的元素重复以上的步骤,除了最后一个。
4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
  • 性能
1. 时间复杂度:O(n^2)

(二)、图例


在这里插入图片描述


(三)、Java代码

  • bubbleSort
	/**
	 * 冒泡排序
	 * 
	 * 不正宗,但简单呀
	 * @param arrs
	 */
	public void bubbleSort(int[] arrs) {
		int n = arrs.length;
		
		for(int i=0; i<n; i++) {
			for(int j=0; j<n-1-i; j++) {
				if(arrs[j] > arrs[j+1]) {
					swap(arrs, j, j+1);
				}
			}
		}
	} // bubbleSort
  • testOfBubbleSort
	/**
	 * 测试冒泡排序
	 */
	public static void testOfBubbleSort() {
		int[] arrs = { 5, 11, 1, 0, -1, 15, 20, 100, -99 };
		Sort sort = new Sort();

		sort.bubbleSort(arrs);
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]);
			System.out.print(" ");
		}
	}
  • 输出样例
冒泡排序:
-99 -1 0 1 5 11 15 20 100 

四、源码

package sort;

public class Sort {

	/**
	 * 直接插入排序
	 * 
	 * @param arrs 待排序数组
	 */
	public void insertionSort(int[] arrs) {
		int n = arrs.length;

		for (int i = 0; i < n; i++) {

			// 1. 寻找元素 arrs[i] 合适的插入位置
			for (int j = i; j > 0; j--) {

				// 2. 找到合适位置就交换
				if (arrs[j] < arrs[j - 1]) // 决定升降序
					swap(arrs, j, j - 1);
				else
					break;
			}
		}
	} // insertionSort

	/**
	 * 数组两个位置交换
	 * 
	 * @param arrs
	 * @param i
	 * @param j
	 */
	private void swap(int[] arrs, int i, int j) {
		int temp = arrs[i];
		arrs[i] = arrs[j];
		arrs[j] = temp;
	} // swap

	/**
	 * 测试直接插入排序
	 */
	public static void testOfInsertionSort() {
		int[] arrs = { 5, 11, 1, 0, -1, 15, 20, 100, -99 };
		Sort sort = new Sort();

		sort.insertionSort(arrs);
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]);
			System.out.print(" ");
		}
	}

	/**
	 * 希尔排序
	 * 
	 * @param arrs
	 */
	public void shellSort(int[] arrs) {
		int n = arrs.length;

		// 1. 以n/2为间隔(增量),直到增量为1
		for (int step = n / 2; step >= 1; step /= 2) {

			// 2. 直接插入排序
			for (int i = step; i < n; i++) {
				// j每次递减是减少step那么多
				for (int j = i; j > step - 1; j -= step) {
					if (arrs[j - step] > arrs[j])
						swap(arrs, j - step, j);
					else
						break;
				}
			}
		}
	} // shellSort

	/**
	 * 测试希尔排序
	 */
	public static void testOfShellSort() {
		int[] arrs = { 5, 11, 1, 0, -1, 15, 20, 100, -99 };
		Sort sort = new Sort();

		sort.shellSort(arrs);
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]);
			System.out.print(" ");
		}
	}

	/**
	 * 冒泡排序
	 * 
	 * @param arrs
	 */
	public void bubbleSort(int[] arrs) {
		int n = arrs.length;

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n - 1 - i; j++) {
				if (arrs[j] > arrs[j + 1]) {
					swap(arrs, j, j + 1);
				}
			}
		}
	} // bubbleSort

	/**
	 * 测试冒泡排序
	 */
	public static void testOfBubbleSort() {
		int[] arrs = { 5, 11, 1, 0, -1, 15, 20, 100, -99 };
		Sort sort = new Sort();

		sort.bubbleSort(arrs);
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]);
			System.out.print(" ");
		}
	}

	public static void main(String[] args) {
		System.out.println("\r\n直接插入排序:");
		testOfInsertionSort();
		System.out.println("\r\n希尔排序:");
		testOfShellSort();
		System.out.println("\r\n冒泡排序:");
		testOfBubbleSort();
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

NoBug.己千之

鼓励,鼓励,更加努力

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

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

打赏作者

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

抵扣说明:

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

余额充值