上代码(java)
冒泡排序, 堆排序,插入排序,希尔排序,归并排序,快速排序,选择排序
冒泡排序
package sort;
/**
* Created on 2017/6/12
* Author: youxingyang.
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {4, 1, 8, 0, 2, 8, 9, 6, 14, 18, 3};
//sort(arr);
sort1(arr);
for (Integer a : arr) {
System.out.print(a + " ");
}
}
/**
* 标准冒泡排序
* 二层for循环,每次选出一个最值
* 复杂度:O(n*n)
*
* @param arr
*/
private static void sort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}
/**
* 改进版冒泡-用pos记住每次最后一次交换的下标,下次遍历到pos-1下标即可
*
* @param arr
*/
private static void sort1(int[] arr) {
int i = arr.length - 1;
while (i > 0) {
int pos = 0;
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
pos = j;
}
}
i = pos;
}
}
/**
* 不使用第三个变量交换两个数
*
* @param arr
* @param i
* @param j
*/
private static void swap(int[] arr, int i, int j) {
if (i != j) {
//arr[i]被存为和,arr[j]没有变
arr[i] = arr[i] + arr[j];
//arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
arr[j] = arr[i] - arr[j];
//此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
arr[i] = arr[i] - arr[j];
}
}
}
堆排序
package sort;
import java.util.Arrays;
/**
* Created on 2017/6/15
* Author: youxingyang.
*/
/**
* 思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,
* 使之成为一个 堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。
* 然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对 它们作交换,
* 最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。
* 所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
*/
public class HeapSort {
public static void main(String[] args) {
int[] arr = {6, 5, 4, 3, 2, 1, 0};
//留最后一个空位放第一个最大值
for (int i = 0; i < arr.length - 1; i++) {
buildMaxHeap(arr, arr.length - 1 - i);
//交换堆顶最大值与最后一个空位
swap(arr, 0, arr.length - 1 - i);
}
System.out.println(Arrays.toString(arr));
}
/**
* 建立一个最大堆
*
* @param arr
* @param lastIndex
*/
private static void buildMaxHeap(int[] arr, int lastIndex) {
//从最后一个父节点开始建堆
for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
int k = i;
//子节点存在
while (2 * k + 1 <= lastIndex) {
int biggerIndex = 2 * k + 1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的右节点存在
if (biggerIndex < lastIndex) {
//左节点小于右节点
if (arr[biggerIndex] < arr[biggerIndex + 1]) {
biggerIndex++;
}
}
//当前节点值小于两者最大值,把最大值调到堆顶
if (arr[k] < arr[biggerIndex]) {
swap(arr, k, biggerIndex);
//保证k节点的值大于其左右子节点的值
k = biggerIndex;
} else {
break;
}
}
}
}
/**
* 不使用第三个变量交换两个数
*
* @param arr
* @param i
* @param j
*/
private static void swap(int[] arr, int i, int j) {
if (i != j) {
//arr[i]被存为和,arr[j]没有变
arr[i] = arr[i] + arr[j];
//arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
arr[j] = arr[i] - arr[j];
//此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
arr[i] = arr[i] - arr[j];
}
}
}
插入排序
package sort;
import java.util.Arrays;
/**
* Created on 2017/6/15
* Author: youxingyang.
*/
/**
* 思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,
* 使之成为一个 堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。
* 然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对 它们作交换,
* 最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。
* 所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
*/
public class HeapSort {
public static void main(String[] args) {
int[] arr = {6, 5, 4, 3, 2, 1, 0};
//留最后一个空位放第一个最大值
for (int i = 0; i < arr.length - 1; i++) {
buildMaxHeap(arr, arr.length - 1 - i);
//交换堆顶最大值与最后一个空位
swap(arr, 0, arr.length - 1 - i);
}
System.out.println(Arrays.toString(arr));
}
/**
* 建立一个最大堆
*
* @param arr
* @param lastIndex
*/
private static void buildMaxHeap(int[] arr, int lastIndex) {
//从最后一个父节点开始建堆
for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
int k = i;
//子节点存在
while (2 * k + 1 <= lastIndex) {
int biggerIndex = 2 * k + 1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的右节点存在
if (biggerIndex < lastIndex) {
//左节点小于右节点
if (arr[biggerIndex] < arr[biggerIndex + 1]) {
biggerIndex++;
}
}
//当前节点值小于两者最大值,把最大值调到堆顶
if (arr[k] < arr[biggerIndex]) {
swap(arr, k, biggerIndex);
//保证k节点的值大于其左右子节点的值
k = biggerIndex;
} else {
break;
}
}
}
}
/**
* 不使用第三个变量交换两个数
*
* @param arr
* @param i
* @param j
*/
private static void swap(int[] arr, int i, int j) {
if (i != j) {
//arr[i]被存为和,arr[j]没有变
arr[i] = arr[i] + arr[j];
//arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
arr[j] = arr[i] - arr[j];
//此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
arr[i] = arr[i] - arr[j];
}
}
}
希尔排序
package sort;
/**
* Created on 2017/6/12
* Author: youxingyang.
*/
public class ShellSort {
public static void main(String[] args) {
int[] arr = {4, 1, 8, 0, 2, 8, 9, 6, 14, 18, 3};
sort(arr);
for (Integer a : arr) {
System.out.print(a + " ");
}
}
private static void sort(int[] arr) {
int k = arr.length / 2;
while (k >= 1) {
shellSort(arr, k);
k /= 2;
}
}
/**
* 希尔排序: 插入排序 = 希尔排序的增量为1
*
* @param arr
* @param k
*/
private static void shellSort(int[] arr, int k) {
for (int i = k; i < arr.length; i++) {
if (arr[i] < arr[i - k]) {
int j;
int tmp = arr[i];
for (j = i - k; j >= 0 && tmp < arr[j]; j = j - k) {
arr[j + k] = arr[j];
}
arr[j + k] = tmp;
}
}
}
}
归并排序
package sort;
import java.util.Arrays;
/**
* Created on 2017/6/15
* Author: youxingyang.
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {6, 5, 4, 3, 2, 1, 0};
sort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private static void sort(int[] arr, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
sort(arr, low, mid);
sort(arr, mid + 1, high);
merge(arr, low, mid, high);
}
}
/**
* 归并
* 将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列
*
* @param arr 待排序数组
* @param low 开始位置
* @param mid 二分位置
* @param high 结束位置
*/
private static void merge(int[] arr, int low, int mid, int high) {
int[] tmp = new int[high - low + 1];
int i = low;
int j = mid + 1;
int k = 0;
//把较小的值移入新数组tmp中
while (i <= mid && j <= high) {
if (arr[i] < arr[j]) {
tmp[k++] = arr[i++];
} else {
tmp[k++] = arr[j++];
}
}
//左边剩余的数移入
while (i <= mid) {
tmp[k++] = arr[i++];
}
//右边剩余的数移入
while (j <= high) {
tmp[k++] = arr[j++];
}
//用tmp数组的值覆盖原数组
for (int l = 0; l < tmp.length; l++) {
arr[l + low] = tmp[l];
}
}
}
快速排序
package sort;
/**
* Created on 2017/6/12
* Author: youxingyang.
*/
public class quickSort {
public static void main(String[] args) {
int[] arr = {4, 1, 8, 0, 2, 8, 9, 6, 14, 18, 3};
sort(arr, 0, arr.length - 1);
for (Integer a : arr) {
System.out.print(a + " ");
}
}
private static void sort(int[] arr, int low, int high) {
if (low < high && arr.length > 0) {
int index = partition(arr, low, high);
sort(arr, low, index - 1);
sort(arr, index + 1, high);
}
}
/**
* 按照key基准给数组分区
*
* @param arr 数组
* @param low 数组初始下标
* @param high 数组最大下标
* @return key基准的下标
*/
private static int partition(int[] arr, int low, int high) {
int key = arr[low];
while (low < high) {
while (arr[high] >= key && low < high) {
high--;
}
arr[low] = arr[high];
while (arr[low] <= key && low < high) {
low++;
}
arr[high] = arr[low];
}
arr[high] = key;
return high;
}
}
选择排序
package sort;
import java.util.Arrays;
/**
* Created on 2017/6/12
* Author: youxingyang.
*/
public class SelectSort {
public static void main(String[] args) {
int[] arr = {6, 5, 4, 3, 2, 1};
sort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 标准选择排序-每次选取一个最值
*
* @param arr
*/
private static void sort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int index = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[index]) {
index = j;
}
}
swap(arr, i, index);
}
}
/**
* 不使用第三个变量交换两个数
*
* @param arr
* @param i
* @param j
*/
private static void swap(int[] arr, int i, int j) {
if (i != j) {
//arr[i]被存为和,arr[j]没有变
arr[i] = arr[i] + arr[j];
//arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
arr[j] = arr[i] - arr[j];
//此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
arr[i] = arr[i] - arr[j];
}
}
}