数据结构排序算法Java实现

数据结构算法总结--排序
package com.company.sort;

import java.util.Arrays;
import java.util.Stack;

public class MaoPao {
    public static void main(String[] args) {
        int[] data = { 15, 13, 1, 5, 20, 12, 8, 9, 11 };
        int[] res = new int[data.length];
        mpsort(data);
        mpsort1(data);
        insertSort(data);
        selectSort(data);
        guibingSort(data);
        create(data);
        quickMain(data);
        res = quickSort(data,0,data.length-1);
        System.out.println("递归快排"+Arrays.toString(res));
    }
    //最原始的冒泡排序
    public static void mpsort(int[] data){
        int len = data.length;
        for(int i=len-1;i>0;i--){   //一共需要比较len-1次
            for (int j=0;j<i;j++){    //从头开始到i;
                if(data[j]<data[j+1]){   //把最小的沉到最下面
                    int temp = data[j+1];
                    data[j+1]=data[j];
                    data[j]=temp;
                }
            }
        }
        System.out.println("原始冒泡"+Arrays.toString(data));
    }
    //冒泡排序
    public static void mpsort1(int[] nums){
        int len = nums.length;
        boolean flag = true;
        while(flag && len>0){
            for(int j=1;j<len;j++){
                if(nums[j-1]<nums[j]){
                    swap(nums[j-1],nums[j]);
                    flag=true;
                }
            }
            len--;
        }
        System.out.println("冒泡排序"+Arrays.toString(nums));
    }
    public static void swap(int m,int n){
        int temp = m;
        m=n;
        n=m;
    }
    //简单插入排序
    public static void  insertSort(int[] nums){
        int len = nums.length;
        int i,j;
        for (i =1;i<len;i++){         //从第二个数开始,然后倒序查找该数的应该的插入位置
            int temp = nums[i];
             for (j=i;j>0 && nums[j-1]<temp;j--){   //nums[j-1]<temp 还是大于,决定最后是升序排列还是降序排列
                nums[j]=nums[j-1];//向后移动一次
             }
             nums[j]=temp;
        }
        System.out.println("插入排序"+Arrays.toString(nums));
    }
    //选择排序
    public static void selectSort(int[] nums){
        int len = nums.length;
        for(int i=0;i<len;i++){
            int index = i;
            for(int j=i+1;j<len;j++){
                if(nums[j]<nums[index]){
                    index=j;
                }
            }
            swap(nums[i],nums[index]);  //这里是交换而不是直接赋值
        }
        System.out.println("选择排序"+Arrays.toString(nums));
    }

    //2路归并排序,先将一个数组分成两个子序列,然后用归并排序将两个数组合并成一个序列
    public static void guibingSort(int[] nums){
        int left = 0;
        int right = nums.length-1;
        merge(nums,left,right);
        System.out.println("归并排序"+Arrays.toString(nums));
    }
    public static void merge(int[] nums,int left,int right){
        if(left>=right){return;}
        int mid = left+(right-left)/2;
        merge(nums,left,mid);
        merge(nums,mid+1,right);
        mergeTwo(nums,left,mid,right);
    }
    public static void mergeTwo(int[] nums,int left, int mid,int right){
        int i=left;
        int j= mid+1;
        int[] temp = new int[right-left+1];
        int index = 0; //指定额外的一个存放数据的新数组
        while (i<=mid && j<=right){
            if (nums[i]<nums[j]){  //归并排序不能在这里修改大于小于号来实现,升序排列还是降序排列
                temp[index++]=nums[i++];
            }else {
                temp[index++]=nums[j++];
            }
        }
        while (i<=mid){
            temp[index++]=nums[i++];
        }
        while (j<right){
            temp[index++]=nums[j++];
        }
        for (int kk=0;kk<temp.length;kk++){
            nums[left+kk]=temp[kk];
        }
    }

    //堆排序
    //构造大顶堆
    public static void create(int[] nums){
        int len = nums.length-1;
        for(int i=(len-1)/2;i>=0;i--){
            fixDown(nums,i,len);
        }
        for (int j=len;j>=0;j--){
            int temp = nums[j];
            nums[j]=nums[0];
            nums[0]=temp;
            fixDown(nums,0,j-1);
        }
        System.out.println("堆排序"+Arrays.toString(nums));
    }
    public static void fixDown(int[] nums,int i,int len){
        int temp = nums[i];
        int son = i*2+1;
        while(son<=len){
            if(son+1<=len && nums[son]<nums[son+1]) son++;   //这里一定要有son+1<=len 还包括等号
            if(nums[son]<temp){
                break;
            }
            nums[i]=nums[son];
            i=son;
            son=i*2+1;
        }
        nums[i]=temp;   //最后跳出循环的时候一定是son超过了len的限制,所以最后应该把temp,放在nums[i]的位置上
    }


//快速排序的递归和非递归
    public static int partition(int[] nums,int left, int right){
        int i=left;
        int j = right;
        int pivot = nums[i];
        while(i<j){
            while (i<j && nums[j]>=pivot)j--;
            nums[j]=nums[i];
            while (i<j && nums[i]<=pivot)i++;
            nums[i]=nums[j];
        }
        nums[i]=pivot;
        return i;
    }
    public static void quickMain(int[] nums){
        int left = 0;
        int right = nums.length-1;
        Stack<Integer> stack = new Stack<>();
        stack.push(left);
        stack.push(right);
        while (!stack.isEmpty()){
            int i=stack.pop();  //右指针
            int j=stack.pop();   //左指针
            int index = partition(nums,i,j);
            if(index>j){
                stack.push(j);
                stack.push(index-1);
            }
            if (index<i){
                stack.push(index+1);
                stack.push(i);
            }
        }
        System.out.println("非递归快排"+Arrays.toString(nums));
    }
///递归
    public static int[] quickSort(int[] nums,int left,int right){
        if (left>right) return null;
        int i = left;
        int j = right;
        int pivot = nums[left];
        while (i<j){
            while (i<j && nums[j]>=pivot )j--;
            if (i<j) nums[i]=nums[j];
            while (i<j && nums[i]<=pivot) i++;
            if (i<j)nums[j]=nums[i];
        }
        nums[i]=pivot;
        quickSort(nums,left,i-1);
        quickSort(nums,i+1,right);
        return nums;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值