(java)六种常见排序

31 篇文章 0 订阅

源码下载http://download.csdn.net/download/crazyzxljing0621/9966908 

其实还有很多需要学习和了解的算法等有时间继续更新微笑

概述

冒泡,选择很稳定

基本有序的情况下插入排序效率高

希尔排序依靠希尔增量来进行调整性能。

快速排序常年三好生,并归排序考验递归

冒泡排序:两两比对

插入排序:有序则跳过无序则,i-1与i交换

并归排序:拆分再拆分,类似树一样,然后叶子节点依次比较左树比较完,比较同级右树。

快速排序:以一个值为基准,比他大的放到他后面,比他小的放到他前面依次递归左右,[3,,1,5,34],基准值为3第一执行后[1,5]3[34]以此类推

选择排序:不断把最小的放到顶部,在过程中不断的会把小值向前移动,

希尔排序:通过希尔增量对数据进行分组,不断对组内只进行两两比对交换,[43,1,23,5,7,2]增量为3 [43,5][1,7][23,2]


Run.java

package com.algorithm;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.algorithm.sort.BubbleSort;
import com.algorithm.sort.InsertionSort;
import com.algorithm.sort.MergeSort;
import com.algorithm.sort.QuickSort;
import com.algorithm.sort.SelectionSort;
import com.algorithm.sort.ShellSort;
import com.algorithm.utils.AOP;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 【排序算法】</br>
 * 冒泡排序 O(n2)</br>
 * 选择排序 O(n2)</br>
 * 插入排序 O(n2)</br>
 * 希尔排序 O(n1.5)</br>
 * 快速排序 O(N*logN)</br>
 * 归并排序 O(N*logN)</br>
 * 
 * @author Allen 2017年8月31日
 */
public class Run {
	/** class Constant **/
	private final static String EXECUTE_METHOD = "execute";
	private final static Class<?>[] CLASSES = { BubbleSort.class, SelectionSort.class, InsertionSort.class,
			ShellSort.class, QuickSort.class, MergeSort.class };

	public static void main(String[] args) {
		try {
			new String();
			new Run().execute();
		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException
				| IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	private void execute() throws ClassNotFoundException, NoSuchMethodException, SecurityException,
			IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		for (Class<?> clazz : CLASSES) {
			Method method = Class.forName(clazz.getName()).getMethod(EXECUTE_METHOD);
			AOP.before(method.getAnnotation(Alias.class).key(), method.getAnnotation(Type.class).key());
			method.invoke(null);
			AOP.after(method.getAnnotation(Type.class).key());
		}

	}
}


1.冒泡排序

package com.algorithm.sort;

import com.algorithm.utils.Data;
import com.algorithm.utils.DataType;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 冒泡排序
 * 
 * @author Allen 2017年8月31日
 *
 */

public class BubbleSort {

	/**
	 * @see 两两比对,将最大的放到后边,j<i确保了不用再去比对已成型的数据
	 *   
	 */
	@Alias(key = "冒泡排序")
	@Type(key = DataType.LIST_TYPE)
	public static void execute() {
		for (int i = Data.LIST.length - 1; i > 0; i--) { 
			for (int j = 0; j < i; j++) {
				if (Data.LIST[j] > Data.LIST[j + 1]) {
					Data.LIST[j] ^= Data.LIST[j + 1];
					Data.LIST[j + 1] ^= Data.LIST[j];
					Data.LIST[j] ^= Data.LIST[j + 1]; 
				}
			}
		}
	}
}

2.插入排序

package com.algorithm.sort;

import com.algorithm.utils.Data;
import com.algorithm.utils.DataType;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 插入排序
 * 
 * @author Allen 2017年9月1日
 *
 */
public class InsertionSort {

	/**
	 * @see 从index 1开始索引比对是否是有序序列,如果i比i-1大则认定无序并进入换位
	 * 
	 * 例:[1][6][8][22][44][3][77]</br>
	 *    Data.LIST = new Integer[] {1,6,8,22,44,3,77 };
	 * 1.为什么从1开始,因为是i与i-1的比对
	 * 2.1,6,8,22,44全为有序不进入if
	 * 3.index 5 值为3
	 * 4.3比44小,无序则进入if
	 * 5.先把3的值保存到temp
	 * 6.从i-1开始内循环,也就是说从44,22,8,6,1开始依次查看是否比3大如果大,则依次移动
	 */
	@Alias(key = "插入排序")
	@Type(key = DataType.LIST_TYPE)
	public static void execute() {
		int j;
		for (int i = 1; i < Data.LIST.length; i++) {
			if (Data.LIST[i] < Data.LIST[i - 1])// 不是升序的就进来
			{
				int temp = Data.LIST[i];
				for (j = i - 1; j >= 0 && Data.LIST[j] > temp; j--) {
					Data.LIST[j + 1] = Data.LIST[j];
				}
				Data.LIST[j + 1] = temp;
			}

		}

	}
}

3.并归排序

package com.algorithm.sort;

import com.algorithm.utils.Data;
import com.algorithm.utils.DataType;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 并归排序
 * 
 * @author Allen 2017年9月1日
 *
 */
public class MergeSort {

	/**
	 * @see 并归就是把序列拆开分别比对最后在合并到一起
	 * 1.并归排序就是把数组分组
	 * 2.分组到最小单位,然后左右侧开始自左至右比较大小
	 * 3.最后并到集合中
	 */
	@Alias(key = "并归排序")
	@Type(key = DataType.LIST_TYPE)
	public static void execute() {
		mergeSort(Data.LIST, 0, Data.LIST.length - 1);
	}

	private static void merge(Integer[] a, int low, int mid, int high) {
		int[] temp = new int[high - low + 1];
		int i = low; 
		int j = mid + 1; 
		int k = 0;
		while (i <= mid && j <= high) {
			if (a[i] < a[j]) {
				temp[k++] = a[i++];
			} else {
				temp[k++] = a[j++];
			}
		}
		while (i <= mid) {
			temp[k++] = a[i++];
		}
		while (j <= high) {
			temp[k++] = a[j++];
		}
		for (int k2 = 0; k2 < temp.length; k2++) {
			a[k2 + low] = temp[k2];
		}
	}
	private static void mergeSort(Integer[] a, int low, int high) {
		int mid = (low + high) / 2;
		if (low < high) {
			mergeSort(a, low, mid);
			mergeSort(a, mid + 1, high);
			merge(a, low, mid, high);
		}

	}
}

4.快速排序

package com.algorithm.sort;

import com.algorithm.utils.Data;
import com.algorithm.utils.DataType;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 快速排序
 * 
 * @author Allen 2017年9月1日
 *
 */
public class QuickSort {

	/**
	 * @see 列出一个元素作为基准值,以他为点把大于他的放到后边,小于他的放到前边,依次得出排序结果
	 * 
	 * 例: 67, 23, 89, 35, 28, 90, 10, 24, 0 </br>
	 * 1.设定基准为67 
	 * 2.设定当前数组查找起点和终点
	 * 3.默认起点0,终点为list.size - 1
	 * 4.以保存下我们的基准值到temp
	 * 5.如果0大于67,那么指针j--
	 * 6.否则判断起点是否比终点小(以防对 0 1 这样进行置换)
	 * 7.替换 值 0到 index 0的位置
	 * 8.数组成为 0 23 89 35 28 90 10 24,并移动指针 i++ i = 1
	 * 9.再判断index 1 23是否比67小
	 * 10.true比67小 i++,继续移动指针,找到89比67大 i=2
	 * 11.替换 89的位置到0
	 * 12. 0 23 89 35 28 90 10 99 89 j-- j=7
	 * 13.while i <j 确保头尾指针还没有遇到对方
	 * 14.99大于67, j-- 指针右移,99位置不用动 j=6
	 * 15.10不大于67则调整值 i++ i=3
	 * 16.0 23 10 35 28 90 10 99 89
	 * 17.35小于67 28小于67 i=5 
	 * 18.i=5 j=6 发现90大于67
	 * 19.0 23 10 35 28 90 90 99 89
	 * 20.j-- j=5
	 * 21. while(false)
	 * 22.改变i=5的值为基准值 67
	 * 23.0 23 10 35 28 67 90 99 89
	 * 24.以基准值来看
	 * 25.[0 23 10 35 28] 67 [90 99 89] 明确的以基准值分为了小于基准和大于基准两个阵营
	 * 26.返回i的位置,也就是返回基准值当前所在的数组索引点
	 * 27.递归传入起点0,结束点是基准点-1
	 * 28.[0 23 10 35 28]进行排序
	 * 29.0为基准点,这里0后面的23 10 35 28都大于0所以这次排序自然会在j--到0然后if false的情况下结束
	 * 30.i为0,递归0到-1 break
	 * 31.递归1到end end为4
	 * 32.23位基准i=1 j=4
	 * 33.28 35大于23  i=2
	 * 34.交换 j=2 i=2 10 10 35 28 
	 * 35.结束循环 10 23 35 28以此类推
	 */
	@Alias(key = "快速排序")
	@Type(key = DataType.LIST_TYPE)
	public static void execute() {
		sort(Data.LIST, 0, Data.LIST.length - 1);
	}

	private static void sort(Integer[] a, int start, int end) {
		// 递归快速排序
		int pivotLoc = 0;// 中心点
		if (start < end) {
			pivotLoc = quick(a, start, end);
			sort(a, start, pivotLoc - 1);
			sort(a, pivotLoc + 1, end);
		}
	}

	private static int quick(Integer[] targetArr, int start, int end) {
		int i = start, j = end;
		Integer key = targetArr[start];
		while (i < j) {
			while (j > i && targetArr[j] >= key) {
				j--;
			}
			if (i < j) {
				targetArr[i] = targetArr[j];
				i++;
			}
			while (i < j && targetArr[i] <= key) {
				i++;
			}
			if (i < j) {
				targetArr[j] = targetArr[i];
				j--;
			}
		}
		targetArr[i] = key;
		return i;
	}
}

5.选择排序

package com.algorithm.sort;

import com.algorithm.utils.Data;
import com.algorithm.utils.DataType;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 选择排序
 * 
 * @author Allen 2017年9月1日
 *
 */
public class SelectionSort {

	/**
	 * @see 索引得到最小值放到顶部,之后不再索引顶部已成型的数据
	 *  
	 * 例:[64] [77] [3] [1] [6]</br>
	 * 1.最小索引默认为 i,minxIndex=i=0</br>
	 * 2.从64开始</br>
	 * 3.进入内循环</br>
	 * 4.64是否比77大</br>
	 * 5.否</br>
	 * 6.64是否比3大</br>
	 * 7.是</br>
	 * 8.最小索引标记minIndex为j,j为2</br>
	 * 9.3是否比1大</br>
	 * 10.是</br>
	 * 11.最小索引为3</br>
	 * 12.1是否比6大</br>
	 * 13.否</br>
	 * 14.内循环结束</br>
	 * 15.minIndex=3</br>
	 * 16.3!=0</br>
	 * 17.交换list[3]和list[0]的位置</br>
	 * 18.1,77,3,64,6</br>
	 * 19.i=1,minIndex=1,最小值暂定为77</br>
	 * 20.77是否比3大</br>
	 * 21.是</br>
	 * 22.minIndex=2</br>
	 * 23.3是否比64大</br>
	 * 24.否</br>
	 * 25.3是否比6大</br>
	 * 26.否</br>
	 * 27.内循环结束</br>
	 * 28.minIndex=2</br>
	 * 29.2!=1</br>
	 * 30.交换list[2]和list[1]</br>
	 * 31.1,3,77,64,6</br>
	 * 32.77是否大于64,i=2</br>
	 * 33.是</br>
	 * 34.minIndex=3</br>
	 * 35.64是否大于6</br>
	 * 35.minIndex=4</br>
	 * 36.内循环结束,交换</br>
	 * 37.1,3,6,64,77</br>
	 * 38.i=3</br>
	 * 39.64不大于77</br>
	 * 40.minIndex == i 3==3</br>
	 * 44.break</br>
	 * 45.i=4 退出循环</br>
	 * 46.外循环是list长度-1,因为不-1也没有可以比较的lastIndex+1的内容了</br>
	 * 
	 */
	@Alias(key = "选择排序")
	@Type(key = DataType.LIST_TYPE)
	public static void execute() {
		for (int i = 0; i < Data.LIST.length - 1; i++) {
			int minIndex = i;
			for (int j = i + 1; j < Data.LIST.length; j++) {
				if (Data.LIST[minIndex] > Data.LIST[j]) {
					minIndex = j;
				}
			}
			if (minIndex != i) {
				Data.LIST[i] ^= Data.LIST[minIndex];
				Data.LIST[minIndex] ^= Data.LIST[i];
				Data.LIST[i] ^= Data.LIST[minIndex];
			}
		}

	}
}


6.希尔排序

package com.algorithm.sort;

import com.algorithm.utils.Data;
import com.algorithm.utils.DataType;
import com.algorithm.utils.annotations.Alias;
import com.algorithm.utils.annotations.Type;

/**
 * 希尔排序
 * 
 * @author Allen 2017年9月1日
 *
 */
public class ShellSort {

	/**
	 * @see 选择通过增量分组进行插入排序,不断缩小增量
	 * 
	 *  例: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 </br>
	 * 1.通过增量len/2 = 5
	 * 2.拆成[10,5][9,4][8,3][7,2][6,1]
	 * 3.之后每组进行插入排序
	 * 4.结果5,4,3,2,1,10,9,8,7,6
	 * 5.len/=2,增量进化到2
	 * 6. 5,3调换,4,2调换,5,1调换以此类推
	 */
	@Alias(key = "希尔排序")
	@Type(key = DataType.LIST_TYPE)
	public static void execute() {
		for (int gap = Data.LIST.length / 2; gap > 0; gap /= 2) {
			for (int j = gap; j < Data.LIST.length; j++) {
				int temp = Data.LIST[j];
				for (int k = j - gap; k >= 0 && Data.LIST[k] > temp; k -= gap) {
					Data.LIST[k + gap] ^= Data.LIST[k];
					Data.LIST[k] ^= Data.LIST[k + gap];
					Data.LIST[k + gap] ^= Data.LIST[k];
				}
			}
		}
	} 
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值