import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class SortDemo1 {
// 1.插入排序:直接插入排序,二分法排序,希尔排序
// (1).直接插入排序:从后往前比较插入(第一个数可以不用比较)
// (2).二分法排序:取low.mid,hight,进行比较,当low>height时low或者height+1为插入点,low与要插入的数据之间的数据后移一位
// (3).希尔排列:将数组分成length/2../2的小组,每个小组进行直接插入排序
// 2.选择排序:简单选择排序,堆排序
// (4).简单选择排序:每次找出最小值,然后放在最前面
// (5).堆排序:利用二叉树的形式,从最后一个数开始比较,将最大的数往上推,每循环一次,最上面的数为最大,取出并用为排序的最后一个数替换(注意:此循环可以少比较一次,因为最后只剩两个数的时候也会进行比较,这时就已经替换了。所有只剩一个值时极为最大值。)
// 3.交换排序:冒泡排序,快速排序
// (6).冒泡排序:相邻两个数一次比较,大的数往下沉
// (7).快速排序:取小组第一个数为基数,通过从后往前比较,将比基数小的数放在基数的右边,再通过从前往后比较,将比基数大的数放在基数的右边,只到左右两边比较完之后,将已基数为中点,将数组一分为二,利用递归,再次比较(递归)
// 4.基数排序
// (8).技术排列:从低位进行比较(与我们通常比较高位大小进行比较相反),利用10个(0-9共十个数)List存放数据
// 5,归并排序
// (9).归并排序:将数组一分为二,利用递归,最后分成一组一个,进行有序排列
public static void main(String[] args) {
ArrayList<Long> times = new ArrayList<Long>();
int[] data;
long start, end;
data = getRandom();
start = System.currentTimeMillis();
// 直接插入排序
start = System.currentTimeMillis();
toStraightInsertionSort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("直接插入排序: " + Arrays.toString(data));
// 二分法排序
data = getRandom();
start = System.currentTimeMillis();
toBinarySort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("二分法排序: " + Arrays.toString(data));
// 希尔排序
data = getRandom();
start = System.currentTimeMillis();
toShellSort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("希尔排序: " + Arrays.toString(data));
System.out.println(
"*************************************************************************************");
// 直接插入排序
data = getRandom();
start = System.currentTimeMillis();
toStraightInsertionSort1(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("直接插入排序: " + Arrays.toString(data));
// 希尔排序
data = getRandom();
start = System.currentTimeMillis();
toShellSort1(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("希尔排序: " + Arrays.toString(data));
System.out.println(
"*************************************************************************************");
// 直接选择排序
data = getRandom();
start = System.currentTimeMillis();
toSimpleSelectionSort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("直接选择排序: " + Arrays.toString(data));
// 堆排序
data = getRandom();
start = System.currentTimeMillis();
toHeapSort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("堆排序: " + Arrays.toString(data));
// 冒泡排序
data = getRandom();
start = System.currentTimeMillis();
toBubbleSort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("冒泡排序: " + Arrays.toString(data));
// 快速排序
data = getRandom();
start = System.currentTimeMillis();
toQuickSort(data, 0, data.length - 1);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("快速排序: " + Arrays.toString(data));
// 基数排序
data = getRandom();
start = System.currentTimeMillis();
toRadixSort(data);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("基数排序: " + Arrays.toString(data));
// 归并排序
data = getRandom();
start = System.currentTimeMillis();
toMergeSort(data, 0, data.length - 1);
end = System.currentTimeMillis();
System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
System.out.println("归并排序: " + Arrays.toString(data));
System.out.println("###########################################");
System.out.println("所有排序耗时表:"+times.toString());
}
/**
* 直接插入排序
*
* @param data
*/
public static void toStraightInsertionSort(int[] data) {
int temp;// 保存要插入的值
for (int i = 1; i < data.length; i++) {
// 从后往前进行比较并插入
temp = data[i];
int j;
for (j = i - 1; j >= 0; j--) {
if (temp < data[j]) {// 后移一位
data[j + 1] = data[j];
} else {// 找到插入位置
break;
}
}
// 插入值
data[j + 1] = temp;
}
}
/**
* 二分法排序
*
* @param data
*/
public static void toBinarySort(int[] data) {
int low, mid, height, temp;
for (int i = 1; i < data.length; i++) {
low = 0;
height = i - 1;
temp = data[i];// 保存待插入的值
while (low <= height) {
mid = (height + low) / 2;// 更新中间节点
if (data[i] > data[mid]) {// 更新左节点
low = mid + 1;
} else {
height = mid - 1;
}
}
// 要插入的位置是low或者height+1
// 数据往后移一位(low与i-1之间的数)
for (int j = i - 1; j >= low; j--) {
data[j + 1] = data[j];
}
// 插入值
data[low] = temp;
}
}
/**
* 希尔排列
*
* @param data
*/
public static void toShellSort(int[] data) {
int temp;
for (int d = data.length / 2; d > 0; d /= 2) {
for (int i = d; i < data.length; i++) {
// 对每一小组的数据进行直接插入排列
int j = i - d;
temp = data[i];
for (; j >= 0; j -= d) {
if (temp < data[j]) {// 往后移d位
data[j + d] = data[j];
} else {// 找到插入位置
break;
}
}
// 插入数据
data[j + d] = temp;
}
}
}
/**
* 直接插入排序
*
* @param data
*/
public static void toStraightInsertionSort1(int[] data) {
// 直接插入就类似于每小组就一个
straightInsertionSort(data, 1);
}
/**
* 希尔排列
*
* @param data
*/
public static void toShellSort1(int[] data) {
for (int d = data.length / 2; d > 0; d /= 2) {
straightInsertionSort(data, d);
}
}
/**
* 将希尔与直接插入相同代码
*
* @param data
* @param d
*/
public static void straightInsertionSort(int[] data, int d) {
int temp;
for (int i = d; i < data.length; i++) {
// 对每一小组的数据进行直接插入排列
int j = i - d;
temp = data[i];
for (; j >= 0; j -= d) {
if (temp < data[j]) {// 往后移d位
data[j + d] = data[j];
} else {// 找到插入位置
break;
}
}
// 插入数据
data[j + d] = temp;
}
}
/**
* 简单选择排序
*
* @param data
*/
public static void toSimpleSelectionSort(int[] data) {
int min, index, temp;
for (int i = 0; i < data.length; i++) {
min = data[i];
temp = data[i];
index = i;
for (int j = i; j < data.length; j++) {
if (min > data[j]) {// 更新最小值和记录最小值的下标
min = data[j];
index = j;
}
}
// 将最小值与放在i位置互换
data[i] = data[index];
data[index] = temp;
}
}
/**
* 堆排序
*
* @param data
*/
public static void toHeapSort(int[] data) {
int f, left, right, index, last;// 父节点,左右节点,正在比较的推的最后一个节点,所有未排列的最后一个节点
for (int i = 0; i < data.length - 1; i++) {// 二叉树的格式,最后堆至少是两个,所以循环次数-1,
last = data.length - 1 - i;
index = last;
f = (index - 1) / 2;
for (; f >= 0; f--) {
left = f * 2 + 1;
if (left <= index) {// 左节点要小于比较的最后一个节点
if (left < index) {// 此时有右节点
right = left + 1;
if (data[left] > data[right]) {// 左节点值大于右节点值,二者互换
swap(data, left, right);
}
if (data[f] < data[right]) {// 右节点的值大于父节点的值,二者互换数据
swap(data, right, f);
}
} else {// 没有右节点,
if (data[left] > data[f]) {// 左节点的值大于父节点的值,二者进行交换
swap(data, left, f);
}
}
}
// 比较下一个节点值,更新比较堆的最后一个值,此时一定存在右节点,及index = 右节点的值
index = (f - 1) * 2 + 2;
}
swap(data, 0, last);
}
}
/**
* 指定下标数据互换
*
* @param data
* @param i
* @param j
*/
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
/**
* 冒泡排序
*
* @param data
*/
public static void toBubbleSort(int[] data) {
int temp;
for (int i = 0; i < data.length - 1; i++) {
for (int j = 0; j < data.length - i - 1; j++) {
if (data[j] > data[j + 1]) {// 相邻两个数进行比较,大的往下沉
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
}
/**
* 快速排序: 利用递归
*
* @param data
* @param low
* @param height
*/
public static void toQuickSort(int[] data, int low, int height) {
int l = low, h = height, temp;
if (l < h) {
temp = data[low];
while (l < h) {
// 从后往前查找小于temp的值
while (l < h && temp <= data[h]) {
h--;
}
// 找到小于temp的值
if (l < h) {
data[l++] = data[h];
}
// 从前往后查找比temp大的值
while (l < h && temp >= data[l]) {
l++;
}
// 找到大于temp的值
if (l < h) {
data[h--] = data[l];
}
}
data[l] = temp;
toQuickSort(data, low, l);
toQuickSort(data, l + 1, height);
}
}
/**
* 基数排序
*
* @param data
*/
public static void toRadixSort(int[] data) {
int times = 0, max = data[0];
// 求出最大值,便于得出比较次数(最大位数)
for (int i = 1; i < data.length; i++) {
if (max < data[i]) {
max = data[i];
}
}
// 求出位数
while (max > 0) {
max /= 10;
times++;
}
// 生成10个List
ArrayList<ArrayList<Integer>> queueList = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) {
ArrayList<Integer> item = new ArrayList<Integer>();
queueList.add(item);
}
for (int i = 0; i < times; i++) {
// 分配
for (int j = 0; j < data.length; j++) {
int x = data[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
ArrayList<Integer> item = queueList.get(x);
item.add(data[j]);
queueList.set(x, item);
}
// 更新数组
int count = 0;
for (int k = 0; k < 10; k++) {
while (queueList.get(k).size() > 0) {
data[count] = queueList.get(k).get(0);
queueList.get(k).remove(0);
count++;
}
}
}
}
/**
* 归并排序:利用递归 一分为二,然后进行有序排序
*
* @param data
* @param low
* @param height
*/
public static void toMergeSort(int[] data, int low, int height) {
int mid;
if (low < height) {
mid = (low + height) / 2;
toMergeSort(data, low, mid);
toMergeSort(data, mid + 1, height);
toOrderlySort(data, low, mid, height);
}
}
/**
* 有序排序
*
* @param data
* @param low
* @param mid
* @param height
*/
private static void toOrderlySort(int[] data, int low, int mid, int height) {
int i = low, j = mid + 1, n = mid, m = height;// 将data数组以low,mid,height为界限分成两个部分
// 用于更新数据
int count = 0;
int len = height - low + 1;
int[] temp = new int[len];
// 先比较二个
while (i <= n && j <= m) {
if (data[i] < data[j]) {
temp[count++] = data[i++];
} else {
temp[count++] = data[j++];
}
}
// 只剩一个数组数据没有对比完
while (i <= n) {
temp[count++] = data[i++];
}
while (j <= m) {
temp[count++] = data[j++];
}
// 更新数组数据
for (int k : temp) {
data[low++] = k;
}
}
private static int[] getRandom() {
Random random = new Random();
int len = 100000;
int[] data = new int[len];
for (int i = 0; i < len; i++) {
data[i] = random.nextInt(len);
}
System.out.println("原始数据 :"+Arrays.toString(data));
return data;
}
}
Java 9种基本排列
最新推荐文章于 2024-11-25 00:05:30 发布