源码下载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];
}
}
}
}
}