最近学习了一下数据结构中的内排序,简单的写了一下所有的算法代码,几乎每一行的代码都进行了注释,方便日后复习
package demo;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class A{
/*
直接插入排序
*/
private static void Straight_Insertion_Sort(int[] init){
System.out.print("初始排序:" + Arrays.toString(init) + "\n");
for (int i = 1; i < 10; i++){ //从第二个数开始
System.out.print(init[i] + "为哨兵值:");
if (init[i] < init[i-1]){ //如果这个数大于前面一个数
int j = i - 1; //首先把它前面一个数的序号记下来给j
int value = init[i]; //然后把这个哨兵值保存在value上
init[i] = init[i - 1]; //顶位,把前面一位的值覆盖到这个数上
while ( value < init[j]){ //当哨兵值一直少于j位的数值的时候
init[j + 1] = init[j]; //往后覆盖
j--; //下标往左边走
if (j == -1){ //因为j有可能会变成-1,这时候如果返回while比较的话会出错
init[j + 1] = value;
break;
}
}
init[j + 1] = value; //如果不用置换第一个数的话就用这个
}
System.out.println(Arrays.toString(init));
}
}
/*
希尔排序
*/
private static void Shell_Sort(int[] init){
System.out.print("初始排序:" + Arrays.toString(init) + "\n");
int i,j,r,temp,x=0;
for(r = init.length/2; r >= 1; r /=2){ //初始值r为数组长度的一半
for (i = r; i < init.length; i++){ //初始值i为第二组的第一个数值
temp = init[i]; //把该值赋给temp
j = i - r; //跳到前一组
while(j >= 0 && temp < init[j]){ //当j的值还在范围内而且temp小于该值时
init[j + r] = init[j]; //与直接插入类似的手段
j -= r; //继续向上一组跳
}
init[j + r] = temp;
}
x++;
System.out.println("第"+ x +"步排序:"+ Arrays.toString(init));
}
}
/*
简单选择排序
*/
private static void Simple_Selection_Sort(int[] init){
System.out.println("初始排序:" + Arrays.toString(init));
int j;
for(int i = 0; i < init.length; i++){
int temp = init[i],number = i; //把该数的值与下标记下来
for(j = i + 1; j < init.length; j++){ //从第二位开始找
if(init[j] <= temp){ //如果找到小于它的数,就替换
temp = init[j]; //一直找到最小的那个数
number = j; //记下它的下标值
}
}
if (number != i) { //如果找到了比它小的号
init[i] = init[i] ^ init[number]; //交换位置
init[number] = init[i] ^ init[number];
init[i] = init[i] ^ init[number];
}
System.out.println("第" + i + "次排序:" + Arrays.toString(init));
}
}
/*
堆排序
*/
private static void Swap(int[] init, int left, int right){ //两数交换
int temp;
temp = init[left];
init[left] = init[right];
init[right] = temp;
}
private static int leftchild(int i){ //寻找左子树
return i * 2 + 1;
}
private static void Start_Sort(int[] init, int i, int n){
int father, child;
for(father = init[i]; leftchild(i) < n; i = child){
child = leftchild(i);
if (child != n - 1 && init[child] < init[child + 1]){ //左右子树比较大小
child++;
}
if (father < init[child]){ //父节点与最大的子树结点比较大小
Swap(init, i, child);
} else {
break;
}
}
}
private static void Heap_Sort(int[] init){
System.out.println("初始排序:" + Arrays.toString(init));
int n = 1;
for(int a = init.length/2-1; a >= 0; a--){ //构建大顶堆
Start_Sort(init, a, init.length);
}
for(int a = init.length-1; a > 0; a--){ //每交换一个元素都把长度减少一
Swap(init, 0, a); //把根节点与最后一个叶节点交换
System.out.println("第" + n++ + "次排序:" + Arrays.toString(init));
Start_Sort(init, 0, a);
}
}
/*
冒泡排序
*/
private static void Bubble_Sort(int[] init){ //冒泡排序是最简单的排序算法。。。
System.out.println("初始排序:" + Arrays.toString(init));
int n = init.length , l = 1;
while (n-- != 0) {
for (int i = 0; i < n; i++) {
if (init[i] > init[i + 1]) {
init[i] = init[i] ^ init[i + 1];
init[i + 1] = init[i] ^ init[i + 1];
init[i] = init[i] ^ init[i + 1];
}
}
System.out.println("第" + l++ + "次排序:" + Arrays.toString(init));
}
}
/*
快速排序
*/
private static int Partion(int[] init, int low, int high){
int privatkey = init[low]; //取第一个数作基准
while (low < high){
while(low < high && init[high] >= privatkey){ //先从右边开始寻找小于基准的数
high--;
}
if (low < high){
init[low++] = init[high]; //把小于它的数挖出来,填到它的位置上
}
while(low < high && init[low] <= privatkey){ //然后从左边开始寻找大于基准的数
low++;
}
if (low < high){
init[high--] = init[low]; //把大于它的数挖出来,填到刚才挖出来的数上
}
}
init[low] = privatkey; //把基准的数查到最后i=j的坑上
return low;
}
private static void Quick(int[] init, int left, int right){
if (left < right){
int min = Partion(init, left, right); //取出最后埋坑的下标
Quick(init, left, min - 1); //左半部分递归
Quick(init, min + 1, right); //右半部分递归
}
}
private static void Quick_Sort(int[] init){
System.out.println("初始排序:" + Arrays.toString(init));
Quick(init, 0, init.length-1);
System.out.println("排序完成:" + Arrays.toString(init));
}
/*
归并排序
*/
private static void merge_sort_recursive(int[] arr, int[] result, int start, int end) {
if (start >= end)
return;
int len = end - start, mid = (len >> 1) + start; //长度与中间的下标
int start1 = start, end1 = mid; //左半部分的第一位与最后一位下标
int start2 = mid + 1, end2 = end; //右半部分的第一位与最后一位下标
merge_sort_recursive(arr, result, start1, end1); //递归,一直分
merge_sort_recursive(arr, result, start2, end2);
int k = start; //k用来记录左边第一位的下标
while (start1 <= end1 && start2 <= end2) //让两部分从第一个数开始比较,一直到任意一部分全部走完
result[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++]; //把两者最小的放进新的数组中并且指向下一个数
while (start1 <= end1) //如果左半部分还有剩余
result[k++] = arr[start1++]; //全部直接放进去
while (start2 <= end2) //如果右半部分还有剩余
result[k++] = arr[start2++]; //全部直接放进去
for (k = start; k <= end; k++) //把新数组中的数依次放进旧数组中
arr[k] = result[k]; //覆盖
}
private static void Merge_Sort(int[] init){
System.out.println("初始排序:" + Arrays.toString(init));
int len = init.length;
int[] result = new int[len];
merge_sort_recursive(init, result, 0, len - 1);
}
/*
基数排序
*/
private static void Radix_Sort(int[] init){
System.out.println("初始排序:" + Arrays.toString(init));
int n=1; //选择个位数还是十位数...
int k=0; //k用来选择重新插入init数组的下标
int length=init.length; //数组的长度
int[] order=new int[length]; //用来保存每一列有多少个数字
while(n<100) //取100是因为数组里面全是小于100的数字
{
int[][] bucket = new int[10][length]; //新建一个二维数组用来保存具体数字
for(int num:init) //将原数组里的每个数字放在相应的二维数组中
{
int digit=(num/n)%10; //从个位数开始分类
bucket[digit][order[digit]]=num; //把该数按照个/十位数放入对应的位置
order[digit]++; //使列数加一,表明这一列刚才新增了一个数
}
for(int i=0;i<10;i++) //从0开始遍历每一列,因为一共只有0~9的数字,所以是0~9内循环
{
if(order[i]!=0) //如果这一列中存放了数字
{
for(int j=0;j<order[i];j++) //从这一列的第一个数开始
{
init[k++]=bucket[i][j]; //插入回原本的数组中
}
}
order[i]=0;//插入完整列以后把这条列的个数清0
}
n*=10;
k=0;//将k置0,用于下一轮保存位排序结果
}
System.out.println("排序完成:" + Arrays.toString(init));
}
/*
主入口
*/
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.next();
int max = 100, min = 0;
int[] a;
a = new int[10];
Random random = new Random();
for (int i = 0; i < 10; i++) {
int s = random.nextInt(max - min) + min;
a[i] = s;
}
switch (input) {
case "直接插入排序":
Straight_Insertion_Sort(a);
break;
case "希尔排序":
Shell_Sort(a);
break;
case "简单选择排序":
Simple_Selection_Sort(a);
break;
case "堆排序":
Heap_Sort(a);
break;
case "冒泡排序":
Bubble_Sort(a);
break;
case "快速排序":
Quick_Sort(a);
break;
case "归并排序":
Merge_Sort(a);
break;
case "基数排序":
Radix_Sort(a);
break;
default:
System.out.println("输入错误");
}
}
}
附上网上找的一张图