基于Java的排序算法

顺序/线性查找- O(n)

public class LinearSearch {
    public static void main(String[] args){
        int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        int target=15;
        boolean find_flag = false;
        for(int i =0;i< arr1.length;i++){
            if (target == arr1[i]){
                System.out.printf("Find target %d, the index is %d\n",target,i);
                find_flag = true;
                break;
            }
        }//判断是否找到条件在循环外
        if (!find_flag){
            System.out.println("No existence!");
        }
    }
}

二分查找 - O(log_2 N) 数组必须有序

class BinarySearch{
    public static void main(String[] args) {
        int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100}; //必须是有序数组才行
        int target =5;
        int head = 0 ;//首索引
        int end = arr2.length-1;//尾索引
        boolean flag = false;
        while (head<=end){
            int middle = (head+end) / 2;

            if(target == arr2[middle]){
                System.out.printf("Find target %d, the index is %d\n",target,middle);
                flag = true;
                break;
            }
            if (target > arr2[middle]){
                head = middle+1;
            }else{
                end = middle-1;
            }
        }
        if (!flag){
            System.out.println("No existence!");
        }
    }
}

冒泡排序-O( n 2 n^2 n2)-稳定

public class Bubble {
    public static void main(String[] args) {
        //相邻的两个元素相比
        //第一轮找到一个最大值...第二轮找剩下的最大值...
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

        for (int i =0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }

        System.out.println("\nAfter bubble sort!");
//=========================核心=============================================
        for (int i=0;i< arr.length-1;i++){
        boolean sorted= true;//优化,刚好有序的机会比较低,所以多了几行代码导致时间更长
            for (int j=0;j<arr.length-1-i;j++){ //不用考虑最后的值,因此只需要考虑前len(arr)-1-i个
                if(arr[j]>arr[j+1]){
                    int tmp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=tmp;
                    sorted = false;
                }
            }
            if(sorted)break;
        }
//=========================核心=============================================
        for (int i =0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
    }
}

选择排序-O( n 2 n^2 n2)-不稳定

1.找出最大的元素,然后与最末尾元素进行交换
结果:执行完一轮后,最末尾元素就是最大元素
2.忽略已经找到的元素,重复执行步骤1

public class SelectSOrt {
    public static void main(String[] args) {
        int[] array = new int[]{56,9,10,19,28,37,34};

        for (int i =0;i<array.length;i++){
            System.out.print(array[i]+"\t");
        }

        System.out.println("\nAfter selection sort!");
  //=========================核心=============================================
        for(int end=array.length-1;end>0;end--){ //最后往前
            int maxIndex = 0;//设第一个为最大值
            for(int begin = 1; begin <=end; begin++){//从第二个开始比较
                if (array[maxIndex] <= array[begin]){
                    maxIndex = begin;
                }
            }//结束每一轮轮,交换
            int tmp = array[maxIndex];
            array[maxIndex] = array[end];//放到最后
            array[end]=tmp;
        }
//=========================核心=============================================
        for (int i =0;i<array.length;i++){
            System.out.print(array[i]+"\t");
        }
    }
}

插入排序-O( n 2 n^2 n2)-稳定

遍历元素,设左边已排好序,从右至左遍历序列,将该元素与左边元素进行比较,若该元素小于左边元素则交换

public class InsertSort {
    public static void main(String[] args) {
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

        for (int i=1;i<arr.length;i++){//第0个元素本身有序
            int key = arr[i];
            int j = i-1;//往前比较
            while(j>=0 && arr[j] >key){
                arr[j+1] = arr[j];
                j--;
            }
            arr[j+1]=key; //往后移动一位作为新的参考指标
        }

        for (int i =0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
    }
}

希尔排序-O(n^1.3)-不稳定

需要使用增量排序(间隔)
然后按照间隔进行插入排序(分组再插入排序)
缩小增量排序

public class ShellSort {
    public static void main(String[] args) {
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

        int i,j,inc,key;
        // 初始增量:n/2
        for (inc= arr.length/2;inc>0;inc/=2){
            //插入排序
            for (i=inc;i< arr.length;i++){
                key =arr[i];
                for(j=i;j>=inc && key < arr[j-inc];j-=inc){
                    arr[j]=arr[j-inc];
                }
                arr[j]=key;
            }
        }
        for (i =0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
    }
}

归并排序-O( n l o g n nlogn nlogn)-稳定

首先讲数组进行二分,直到成为单个元素
合并,谁更小放在前面
在这里插入图片描述

public class MergeSort {
    public static void main(String[] args) {
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        merge_sort(arr,arr.length);

        for (int i =0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }

    }
    public static void merge_sort(int[] arr, int n){
        int[] tmpArr = new int[arr.length];
        if(tmpArr.length!=0){
            msort(arr,tmpArr,0,n-1);
        }else
        {
            System.out.println("Fail");
        }
    }

    public static void msort(int[] arr, int[] tmpArr, int left,int right){
        //如果只有一个元素,就不需要划分
        if (left < right){
            //找中间点
            int mid = (left+right)/2;
            //递归划分左半区
            msort(arr,tmpArr,left,mid);
            //递归划分右半区
            msort(arr,tmpArr,mid+1,right);
            //合并
            merge(arr,tmpArr,left,mid,right);
        }
    }
    public static void merge(int[] arr, int[] tmpArr, int left,int mid,int right){
        //标记左半区第一个未排序的元素
        int l_pos = left;
        //标记右半区第一个未排序的元素
        int r_pos = mid+1;
        //临时数组元素下标
        int pos = left;
        //合并
        while (l_pos<=mid && r_pos <=right){
            if(arr[l_pos]<arr[r_pos]){//左半区第一个剩余元素更小
                tmpArr[pos++]=arr[l_pos++];
            }else//右半区第一个元素更小
                tmpArr[pos++]=arr[r_pos++];
        }

        //合并左半区剩余元素
        while (l_pos<=mid)
            tmpArr[pos++]=arr[l_pos++];

        //合并右半区剩余元素
        while (r_pos<=right)
            tmpArr[pos++]=arr[r_pos++];

        //把临时数组中合并后的复制回原来的
        while (left<=right){
            arr[left]=tmpArr[left];
            left++;
        }
    }
}

快速排序-O( n l o g n nlogn nlogn)-不稳定-分治思想

基准,比基准小的放在它前面,比它大的放在它后面
一般是最后一个数作为基准
第一个数由i(第0个数),j一同指向,i不动,j从第一个数开始扫,j扫到比基数小的停下,对换i,j对应值位置,到达基准位置的时候,交换i和pivot所对应的值;换完后i往下移动一位(第1个数)

//QuickSort
    public void QuickSort(int[] arr, int left, int right) {
        //出口条件
        if (left >= right) {
            return;
        }

        //初始变量
        int i = left;
        int j = right;
        int temp = arr[left];
        //移动
        while (i < j) {
            //从右往左
            while (i < j && arr[j] >= temp) {
                j--;
            }
            //放置元素的点
            if (i < j) {
                arr[i++] = arr[j];
            }

            //从左往右
            while (i < j && arr[i] <= temp) {
                i++;
            }
            //放置元素的点
            if (i < j) {
                arr[j--] = arr[i];
            }

            //移动完毕一轮
            System.out.println(Arrays.toString(arr));
        }

        //分治法
        arr[i] = temp;
        //在i的左边都比temp小  左
        QuickSort(arr, left, i - 1);
        //在i的右边都比temp大  右
        QuickSort(arr, i + 1, right);
    }

堆排序-O( n l o g n nlogn nlogn)-不稳定-了解算法

1.对序列进行原地建堆 (第一个数是最大值)
交换堆顶元素与尾元素
堆size-1
对0位置进行1次siftDown操作
直到堆size=1

大顶堆

  • 下标为i的节点的父节点下标:(i-1)/2
  • 下标为i的节点的左孩子下标:i*2+1
  • 下标为i的节点的左孩子下标:i*2+2

二叉树建立


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值