数据结构的Java实现(三)—— 三种简单排序算法

排序是数据处理中十分常见且核心的操作,虽说实际项目开发中很小几率会需要手动实现,毕竟每种语言的类库中都有多种关于排序算法的实现。但是了解这些精妙的思想还是很有好处的。以下简单温习下最基础的三类算法:选择,冒泡,插入。

首先定义一个交换数组元素的函数,以供调用

package yrwan08;

public class Swap {
	/**
	 * 
	 * @param arr
	 * @param a
	 * @param b
	 */
	public static void swap(int[] arr, int a, int b) {
		int temp;
		temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}

//  // 利用异或不可交换相同数据!
//	public static void swap(int[] arr, int a, int b) {
//		arr[a] ^= arr[b];
//		arr[b] ^= arr[a];
//		arr[a] ^= arr[b];
//	}
}

直接选择排序

直接选择排序是每一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

分为三步:

  1. 从待排序序列中,找到最小的元素
  2. 如果最小元素不是待排序序列的第一个元素,将其与第一个元素互换
  3. 从余下的 N - 1 个元素中,找出最小的元素,重复(1)、(2)步,直到排序结束
package yrwan02;

public class SelectSort {
	/**
	 * 改进的选择排序 设置一个变量minIndex存储较小元素的数组下标
	 * 
	 * @param arr
	 */
	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {// 第i轮,i前的元素已排好
			int minIndex = i;
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[minIndex] > arr[j]) {
					minIndex = j;
				}
			}
			if (minIndex != i) {
				Swap.swap(arr, minIndex, i);// 如果minIndex发生变化,则进行交换
			}
		}
	}
}

冒泡排序

冒泡排序的基本思想是,对相邻的元素进行比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。

注:若某一趟中,一次交换都没有进行,则说明剩下的序列已经是有序的,排序操作也就可以完成了

package yrwan02;

public class BubbleSort {
	/**
	 * 冒泡排序 外循环仅代表排序的趟数,内循环表示每轮参与比较的元素下标,向右冒泡
	 * 
	 * @param arr
	 */
	public static void bubbleSort1(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {// 第i轮
			boolean flag = true;
			for (int j = 0; j < arr.length - i - 1; j++) {
				if (arr[j] > arr[j + 1]) {
					Swap.swap(arr, j, j + 1);
				}
				flag = false;
			}
			if (flag) {
				break;// 某一轮没有交换,则意味着已排好顺序
			}
		}
	}
	/**
	 * 冒泡排序 从左冒泡
	 * 
	 * @param arr
	 */
	public static void bubbleSort2(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {// 第i轮,i前的元素已排好
			boolean flag = true;
			for (int j = arr.length - 1; j > i; j--) {
				if (arr[j] < arr[i]) {
					Swap.swap(arr, j, i);
				}
				flag = false;
			}
			if (flag) {
				break;// 某一轮没有交换,则意味着已排好顺序
			}
		}
	}
}

直接插入排序

直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。

package yrwan02;

public class InsertSort {
	/**
	 * 插入排序:每一次将一个待排序的元素,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
	 * 
	 * @param arr
	 */
	public static void insertSort(int[] arr) {
		for (int i = 1; i < arr.length; i++) {// 第i轮,i前的元素已排好
			int temp = arr[i];// 暂存第i个元素
			int j = i;
			while (j > 0 && arr[j - 1] > temp) {// 第j-1个元素与temp比较, 比 temp大就右移
				arr[j] = arr[j - 1];// 右移
				j--;
			}
			arr[j] = temp;
		}
	}
}

测试类:

package yrwan02;

import org.junit.Test;

public class SortTest {
	/**
	 * junit测试类
	 */
	@Test
	public void sortTest() {
		int[] arr = new int[] { 45, 30, 1, 5, -7 };
		for (int i : arr) {
			System.out.print(i + " ");
		}
		System.out.println();
		
//		BubbleSort.bubbleSort(arr);
		SelectSort.selectSort(arr);
//		InsertSort.insertSort(arr);
		
		
		for (int i : arr) {
			System.out.print(i + " ");
		}
	}
}

总结

这三种排序算法的时间复杂度均为O(n2),一般不会选择冒泡排序,虽然冒泡排序书写是最简单的,但是平均性能是没有选择排序和插入排序好的。

选择排序可以把交换次数降低到最低,但是比较次数还是挺大的。当数据量小,并且交换数据相对于比较数据更加耗时的情况下,可以应用选择排序。

在大多数情况下,假设数据量比较小或基本有序时,插入排序是三种算法中最好的选择。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值