先来一个最简单的热热身:冒泡排序
/**
* 冒泡法排序<br/>
*
* 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
* 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
* 针对所有的元素重复以上的步骤,除了最后一个。
* 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
*
* @param numbers
* 需要排序的整型数组
*/
public static int[] soft(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[i] < array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}
难度+1:直接插入排序
/**
* 插入排序<br/>
* <ul>
* <li>从第一个元素开始,该元素可以认为已经被排序</li>
* <li>取出下一个元素,在已经排序的元素序列中从后向前扫描</li>
* <li>如果该元素(已排序)大于新元素,将该元素移到下一位置</li>
* <li>重复步骤3,直到找到已排序的元素小于或者等于新元素的位置</li>
* <li>将新元素插入到该位置中</li>
* <li>重复步骤2</li>
* </ul>
*
* @param numbers
*/
public static int[] soft(int[] array) {
for (int i = 1; i < array.length; i++) {
int temp = array[i] , j;
for ( j = i ; j > 0 && temp < array[j-1]; j--)
array[j] = array[j-1];
array[j] = temp;
}
return array;
}
希尔排序:
public static int[] soft(int[] array) {
for (int i = array.length/2; i > 0; i /= 2) {
for (int j = i; j < array.length; j++) {
int temp = array[j] , k;
for (k = j-i; k >= 0 && temp < array[k]; k-=i)
array[k+i] = array[k];
array[k+i] = temp;
}
}
return array;
}
public static int[] soft(int[] array , int start , int end) {
if (start < end) {
int base = array[start]; // 选定的基准值(第一个数值作为基准值)
int temp; // 记录临时中间值
int i = start, j = end;
do {
while ((array[i] < base) && (i < end))
i++;
while ((array[j] > base) && (j > start))
j--;
if (i <= j) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
} while (i <= j);
if (start < j)
soft(array, start, j);
if (end > i)
soft(array, i, end);
}
return array;
}
归并排序:
/**
* 归并排序<br/>
* <ul>
* <li>申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列</li>
* <li>设定两个指针,最初位置分别为两个已经排序序列的起始位置</li>
* <li>比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置</li>
* <li>重复步骤3直到某一指针达到序列尾</li>
* <li>将另一序列剩下的所有元素直接复制到合并序列尾</li>
* </ul>
*
* @param numbers
*/
public static void mergeSort(int[] numbers, int left, int right) {
int t = 1;// 每组元素个数
int size = right - left + 1;
while (t < size) {
int s = t;// 本次循环每组元素个数
t = 2 * s;
int i = left;
while (i + (t - 1) < size) {
merge(numbers, i, i + (s - 1), i + (t - 1));
i += t;
}
if (i + (s - 1) < right)
merge(numbers, i, i + (s - 1), right);
}
}
// 归并算法实现
private static void merge(int[] data, int p, int q, int r) {
int[] B = new int[data.length];
int s = p;
int t = q + 1;
int k = p;
while (s <= q && t <= r) {
if (data[s] <= data[t]) {
B[k] = data[s];
s++;
} else {
B[k] = data[t];
t++;
}
k++;
}
if (s == q + 1)
B[k++] = data[t++];
else
B[k++] = data[s++];
for (int i = p; i <= r; i++)
data[i] = B[i];
}
直接选择排序:
public static int[] soft(int[] array) {
for (int i = 0; i < array.length; i++) {
int min = i;
for (int j = i+1; j < array.length; j++)
if (array[j] < array[min])
min = j;
if (min != i) {
array = swap(array , i , min);
}
}
return array;
}
private static int[] swap(int[] array, int i, int min) {
// TODO Auto-generated method stub
int temp = array[i];
array[i] = array[min];
array[min] = temp;
return array;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数组大小:");
int n = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
array = soft(array);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
归并排序:
/**
* 归并排序<br/>
* <ul>
* <li>申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列</li>
* <li>设定两个指针,最初位置分别为两个已经排序序列的起始位置</li>
* <li>比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置</li>
* <li>重复步骤3直到某一指针达到序列尾</li>
* <li>将另一序列剩下的所有元素直接复制到合并序列尾</li>
* </ul>
*
* @param numbers
*/
public static void main(String[] args) {
int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
mergeSort(data);
System.out.println("排序后的数组:");
print(data);
}
public static void mergeSort(int[] data) {
sort(data, 0, data.length - 1);
}
public static void sort(int[] data, int left, int right) {
if (left >= right)
return;
// 找出中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
sort(data, left, center);
// 对右边数组进行递归
sort(data, center + 1, right);
// 合并
merge(data, left, center, right);
print(data);
}
/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data
* 数组对象
* @param left
* 左数组的第一个元素的索引
* @param center
* 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right
* 右数组最后一个元素的索引
*/
public static void merge(int[] data, int left, int center, int right) {
// 临时数组
int[] tmpArr = new int[data.length];
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();
}
堆排序:
public static void heap_sort(int[] arrays, int e) {
if (e > 0) {
init_sort(arrays, e);// 初始化堆,找出最大的放在堆顶
// snp(arrays);
arrays[0] = arrays[e] + arrays[0];
arrays[e] = arrays[0] - arrays[e];
arrays[0] = arrays[0] - arrays[e];
// snp(arrays);
heap_sort(arrays, e - 1);
} else {
snp(arrays);
}
}
public static void snp(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
System.out.println();
}
public static void init_sort(int[] arrays, int e) {
int m = (e + 1) / 2;
for (int i = 0; i < m; i++) {
boolean flag = build_heap(arrays, e, i);
// 如果孩子之间有交换,就要重新开始
if (flag) {
i = -1;
}
}
}
// 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
public static boolean build_heap(int arrays[], int e, int i) {
int l_child = 2 * i + 1;// 左孩子
int r_child = 2 * i + 2;// 右孩子
if (r_child > e) { // 判断是否有右孩子,没有的话直接比较,小于交换
if (arrays[i] < arrays[l_child]) {
arrays[i] = arrays[i] + arrays[l_child];
arrays[l_child] = arrays[i] - arrays[l_child];
arrays[i] = arrays[i] - arrays[l_child];
return true;
} else {
return false;
}
}
// 在根与两个孩子之间找出最大的那个值进行交换
if (arrays[i] < arrays[l_child]) {
if (arrays[l_child] > arrays[r_child]) {
// 交换根与左孩子的值
arrays[i] = arrays[i] + arrays[l_child];
arrays[l_child] = arrays[i] - arrays[l_child];
arrays[i] = arrays[i] - arrays[l_child];
return true;
} else {
// 交换根与右孩子的值
arrays[i] = arrays[i] + arrays[r_child];
arrays[r_child] = arrays[i] - arrays[r_child];
arrays[i] = arrays[i] - arrays[r_child];
return true;
}
} else if (arrays[i] < arrays[r_child]) {
// 交换根与右孩子的值
arrays[i] = arrays[i] + arrays[r_child];
arrays[r_child] = arrays[i] - arrays[r_child];
arrays[i] = arrays[i] - arrays[r_child];
return true;
}
return false;
}
public static void main(String[] args) {
int[] a = { 17, 8, 45, 84, 2, 94 };
heap_sort(a, a.length - 1);
}