排序
笔者依次写了几大排序,只是几个比较基础的基本版本,不是优化后的排序算法,日后笔者有空在一一完善,具体理论未涉及
冒泡排序1
选择排序1
插入排序1
希尔排序1
快速排序1
归并排序1
堆排序1
import java.util.Scanner;
public class demoSort {
private static int array[]; //输入数据用数组表示
private static int val; //switch-case判断条件
//冒泡排序
public static void BubbleSort(int arr[]) {
for (int i = 0; i < arr.length - 1; i++) { //外层循环控制排序趟数
for (int j = 0; j < arr.length - 1 - i; j++) { //内层循环控制每一趟排序多少次
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("冒泡排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
//快速排序,利用java多态的特性,仅仅方便输出哦,代码优化而已
public static void quickSort(int arr[]) {
quickSort(arr, 0, arr.length - 1);
System.out.println("快速排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
//https://www.cnblogs.com/MOBIN/p/4681369.html
public static void quickSort(int arr[], int left, int right) {
int temp = 0;
if (left <= right) { //待排序的元素至少有两个的情况
temp = arr[left]; //待排序的第一个元素作为基准元素
while (left != right) { //从左右两边交替扫描,直到left = right
while (right > left && arr[right] >= temp)
right--; //从右往左扫描,找到第一个比基准元素小的元素
arr[left] = arr[right]; //找到这种元素arr[right]后与arr[left]交换
while (left < right && arr[left] <= temp)
left++; //从左往右扫描,找到第一个比基准元素大的元素
arr[right] = arr[left]; //找到这种元素arr[left]后,与arr[right]交换
}
arr[right] = temp; //基准元素归位
quickSort(arr, left, left - 1); //对基准元素左边的元素进行递归排序
quickSort(arr, right + 1, right); //对基准元素右边的进行递归排序
}
}
// 选择排序
public static void selectSort(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;
}
if (index == i)
continue;
else {
int temp;
temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
}
}
System.out.println("选择排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
// 插入排序
public static void insertSort(int arr[]) {
for (int i = 1; i < arr.length; i++) {
int j;
if (arr[i] < arr[i - 1]) {
int temp = arr[i];
for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}
}
System.out.println("插入排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
// 希尔排序
public static void shellSort(int arr[]) {
int increasement = arr.length;
int i, j, k;
do {
// 确定分组的增量
increasement = increasement / 3 + 1;
for (i = 0; i < increasement; i++) {
for (j = i + increasement; j < arr.length; j += increasement) {
if (arr[j] < arr[j - increasement]) {
int temp = arr[j];
for (k = j - increasement; k >= 0 && temp < arr[k]; k -= increasement) {
arr[k + increasement] = arr[k];
}
arr[k + increasement] = temp;
}
}
}
} while (increasement > 1);
System.out.println("希尔排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
//归并排序,注意由于Java多态好用,作者在这想玩一玩多态特性,作为学习者。简而言之,就是在无限套娃
public static void mergeSort(int arr[]) {
mergeSort(arr, 0, arr.length - 1);
System.out.println("归并排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
private static void mergeSort(int a[], int p, int r) {
if (p < r) {
int q = (p + r) / 2;//p表示从子序列的哪个索引开始,q表示子序列中间的位置
mergeSort(a, p, q);
mergeSort(a, q + 1, r);
mergeSort(a, p, q, r);
}
}
private static void mergeSort(int a[], int p, int q, int r) {
// n1和n2分别表示左边序列和右边序列的长度。左边从p开始包括q,右边从q+1开始
int n1 = q - p + 1;
int n2 = r - q;
int L[] = new int[n1];
int R[] = new int[n2];
// k用来表示当前遍历的数组a的索引
int i = 0, j = 0, k = 0;
// 分别给L和R赋值
for (i = 0, k = p; i < n1; i++, k++) {
L[i] = a[k];
}
// 从右边开始
for (j = 0, k = q + 1; j < n2; j++, k++) {
R[j] = a[k];
}
// 比较大小,从小到大排列
for (i = 0, j = 0, k = p; i < n1 && j < n2; k++) {
if (L[i] > R[j]) {
a[k] = R[j];
j++;
} else {
a[k] = L[i];
i++;
}
}//for
// 将两个数组中剩下的数放到a中
if (i < n1) {
for (j = i; j < n1; j++, k++) {
a[k] = L[j];
}
}
if (j < n2) {
for (i = j; i < n2; i++, k++) {
a[k] = R[i];
}
}
}
//堆排序
public static void heapSort(int arr[]) {
if (arr == null || arr.length == 0) {
return;
}
int len = arr.length;
// 构建大顶堆,这里其实就是把待排序序列,变成一个大顶堆结构的数组
buildMaxHeap(arr);
// 交换堆顶和当前末尾的节点,重置大顶堆
for (int i = len - 1; i > 0; i--) {
swap(arr, 0, i);
len--;
heapInit(arr, 0, len);
}
System.out.println("堆排序完成后的数为");
for (int num : arr) {
System.out.print(num + " ");
}
}
private static void buildMaxHeap(int arr[]) {
// 从最后一个非叶节点开始向前遍历,调整节点性质,使之成为大顶堆
for (int i = (int) Math.floor(arr.length / 2) - 1; i >= 0; i--) {
heapInit(arr, i, arr.length);
}
}
private static void heapInit(int arr[], int i, int len) {
// 先根据堆性质,找出它左右节点的索引
int left = 2 * i + 1;
int right = 2 * i + 2;
// 默认当前节点(父节点)是最大值。
int largestIndex = i;
if (left < len && arr[left] > arr[largestIndex]) {
// 如果有左节点,并且左节点的值更大,更新最大值的索引
largestIndex = left;
}
if (right < len && arr[right] > arr[largestIndex]) {
// 如果有右节点,并且右节点的值更大,更新最大值的索引
largestIndex = right;
}
if (largestIndex != i) {
// 如果最大值不是当前非叶子节点的值,那么就把当前节点和最大值的子节点值互换
swap(arr, i, largestIndex);
// 因为互换之后,子节点的值变了,如果该子节点也有自己的子节点,仍需要再次调整。
heapInit(arr, largestIndex, len);
}
}
private static void swap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//输入模块
public static void Scanner() {
Scanner scanner = new Scanner(System.in);
System.out.println();
System.out.println("输入你要求多少个数的排序");
int n = scanner.nextInt();
array = new int[n];
System.out.println("输入你要排序的" + n + "个数,并且按照空格键隔开");
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
}
public static void main(String[] args) {
while (true) {
/*说明这个一个排序说明,有点无线套娃,仔细查看哦*/
/*BubbleSort(array); //冒泡排序
quickSort(array); //快速排序
selectSort(array); //选择排序
insertSort(array); //插入排序
shellSort(array); //希尔排序
mergeSort(array); //归并排序
/heapSort(array); //堆排序*/
Scanner();
System.out.println("----------输入你要选择的排序----------------");
System.out.println("----------1冒泡排序--2快速排序--------------");
System.out.println("----------3选择排序--4插入排序--------------");
System.out.println("----------5希尔排序--6归并排序--------------");
System.out.println("----------7堆排序-------------------------");
Scanner scanner = new Scanner(System.in);
val = scanner.nextInt();
switch (val) {
case 1:
BubbleSort(array); //冒泡排序
break;
case 2:
quickSort(array); //快速排序
break;
case 3:
selectSort(array); //选择排序
break;
case 4:
insertSort(array);//插入排序
break;
case 5:
shellSort(array); //希尔排序
break;
case 6:
mergeSort(array); //归并排序
break;
case 7:
heapSort(array); //堆排序
break;
default:
System.out.println("该输入不存在, 请重新输入\n");
}
//凑个300行玩玩
//凑个300行玩玩
}
}
}