JAVA实现八大内排序算法

最近学习了一下数据结构中的内排序,简单的写了一下所有的算法代码,几乎每一行的代码都进行了注释,方便日后复习

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("输入错误");
            }
        }
}

图片
附上网上找的一张图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值