排序【数据结构与算法Java】

排序

插入类排序

直接插入排序

折半插入排序

希尔排序

package sort1;

/**
 * @author CSDN@日星月云
 * @date 2022/10/30 21:29
 */
public class InsertSort1 {
    public static void main(String[] args) {
        int[]nums={-1,1,2,3,4,5,0,9,8,7,6};//0号不存储有效数字
        //直接插入排序 稳定
//        new InsertSort1().insertSort(nums);
        //改进的直接插入排序 稳定
//        new InsertSort1().insertSortPlus(nums);
        //折半插入排序 稳定
//        new InsertSort1().biInsertSort(nums);
        //增量序列 不稳定
//        new InsertSort1().shellSort(nums,new int[]{4,2,1});
        new InsertSort1().shellSort(nums,new int[]{7,3,1});
        for (int i = 1; i < nums.length; i++) {
            System.out.print(nums[i]+"\t");
        }
    }

    //直接插入排序
    void insertSort(int[] nums){
        for (int i = 2; i <nums.length ; i++) {
            nums[0]=nums[i];//监视哨备份待查记录
            int j;
            for (j = i-1; nums[0]<nums[j]; j--) {
                nums[j+1]=nums[j];//记录后移
            }
            nums[j+1]=nums[0];//插入正确位置
        }
    }

    //待插记录已是当前有序的最大记录,不需要后移排序
    //改进的直接插入排序
    void insertSortPlus(int[] nums){
        for (int i = 2; i <nums.length ; i++) {
            if(nums[i]<nums[i-1]){//如果不小于,就是待插记录已是当前有序的最大记录
                nums[0]=nums[i];//监视哨备份待查记录
                int j;
                for (j = i-1; nums[0]<nums[j]; j--) {
                    nums[j+1]=nums[j];//记录后移
                }
                nums[j+1]=nums[0];//插入正确位置
            }
        }
    }

    //折半插入排序
    //因为插入到有序列中,有折半快速找到位置
    void biInsertSort(int []nums){
        for (int i = 2; i <nums.length ; i++) {
            if(nums[i]<nums[i-1]){//如果不小于,就是待插记录已是当前有序的最大记录
                nums[0]=nums[i];//监视哨备份待查记录
                //折半查找nums[i]插入位置
                int low=1;
                int high=i-1;
                while (low<high){
                    int mid=(low+high)/2;
                    if(nums[0]<nums[mid]){
                        high=mid-1;
                    }else{
                        low=mid+1;
                    }
                }
                for (int j = i-1; j>=low; j--) {
                    nums[j+1]=nums[j];//记录后移
                }
                nums[low]=nums[0];//插入正确位置
            }
        }
    }

    //希尔排序
    //最小增量排序
    void shellInsert(int[] nums,int dk){
        for (int i = dk+1; i <nums.length ; i++) {
            if(nums[i]<nums[i-1]){//如果不小于,就是待插记录已是当前有序的最大记录
                nums[0]=nums[i];//监视哨备份待查记录
                int j;
                for (j = i-dk; j>0&&nums[0]<nums[j]; j-=dk) {
                    nums[j+dk]=nums[j];//记录后移
                }
                nums[j+dk]=nums[0];//插入正确位置
            }
        }
    }
    //dlta 增量序列
    void shellSort(int[] nums,int dlta[]){
        int t=dlta.length;//t为增量序列的长度
        for (int k=0;k<t;k++){
            shellInsert(nums,dlta[k]);
        }
    }


}

交换类排序

冒泡排序

package sort;

/**
 * @author CSDN@日星月云
 * @date 2022/10/30 22:06
 */
public class SwapSort {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5, 0, 9, 8, 7, 6};//0号不存储有效数字
        //冒泡排序
//        new SwapSort1().bubbleSort(nums);
        //改进冒泡排序
        new SwapSort().bubbleSortPlus(nums);
        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i] + "\t");
        }

    }

    public void swap(int [] nums,int i,int j){
        int temp=nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }

    //冒泡排序
    public void bubbleSort(int[] nums){
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j <nums.length-1-i ; j++) {
                if(nums[j]>nums[j+1]){
                    swap(nums,j,j+1);
                }
            }

        }
    }
    //改进冒泡排序
    //如已排好序,直接跳出
    public void bubbleSortPlus(int[] nums){
        boolean flag=true;
        for (int i = 0; i < nums.length&&flag; i++) {
            flag=false;
            for (int j = 0; j <nums.length-1-i ; j++) {
                if(nums[j]>nums[j+1]){
                    swap(nums,j,j+1);
                    flag=true;
                }
            }

        }
    }
}

快速排序

package sort1;

/**
 * @author CSDN@日星月云
 * @date 2022/10/21 23:13
 */
public class QuickSort1 {

    public static void main(String[] args) {
        int[]nums={-1,1,2,3,4,5,0,9,8,7,6};//0号不存储有效数字
        new QuickSort1().qkSort(nums,1, nums.length-1);
        for (int i = 1; i < nums.length; i++) {
            System.out.print(nums[i]+"\t");
        }
    }

    void qkSort(int[]nums,int low,int high){
        int pos;
        if (low<high){
            pos=qkPass(nums, low,high);
            qkSort(nums, low,pos-1);
            qkSort(nums, pos+1,high);
        }
    }




    int qkPass(int[] nums,int low,int high){
        nums[0]=nums[low];//枢轴
        while(low<high){
            while (low<high&&nums[high]>nums[0]) --high;
            nums[low]=nums[high];
            while (low<high&&nums[low]<nums[0]) ++low;
            nums[high]=nums[low];
        }
        nums[low]=nums[0];
        return low;
    }



}

package sort;

/**
 * @author CSDN@日星月云
 * @date 2022/10/21 23:13
 */
public class QuickSort {

    public static void main(String[] args) {
        int[]nums={1,2,3,4,5,0,9,8,7,6};//0号存储有效数字
        new QuickSort().qkSort(nums,0, nums.length-1);
        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i]+"\t");
        }
    }

    void qkSort(int[]nums,int low,int high){
        int pos;
        if (low<high){
            pos=qkPass(nums, low,high);
            qkSort(nums, low,pos-1);
            qkSort(nums, pos+1,high);
        }
    }




    int qkPass(int[] nums,int low,int high){
        int tmp=nums[low];//枢轴
        while(low<high){
            while (low<high&&nums[high]>tmp) --high;
            nums[low]=nums[high];
            while (low<high&&nums[low]<tmp) ++low;
            nums[high]=nums[low];
        }
        nums[low]=tmp;
        return low;
    }



}

选择类排序

简单选择排序

package sort;

/**
 * @author CSDN@日星月云
 * @date 2022/10/30 22:14
 */
public class SelectSort {
    public static void main(String[] args) {
        int[]nums={1,2,3,4,5,0,9,8,7,6};
        //简单选择排序 不稳定
        //树形选择排序
        //堆排序 不稳定
        new SelectSort().selectSort(nums);

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

    public void swap(int [] nums,int i,int j){
        int temp=nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }

    //简单选择排序
    void selectSort(int[] nums){
        for (int i = 0; i < nums.length; i++) {
            int k=i;
            for (int j = i+1; j <nums.length ; j++) {
                if (nums[j]<nums[k]){//k是擂台
                    k=j;
                }
            }
            if (k!=i){
                swap(nums,i,k);
            }
        }

    }

}

树形选择排序

堆排序

package sort1;

import sort.InsertSort;

/**
 * @author CSDN@日星月云
 * @date 2022/10/30 23:04
 */
public class HeapSort1 {
    public static void main(String[] args) {
        int max=Integer.MAX_VALUE;
//        //测试堆的筛选
//        int[]nums={max,72,12,19,33,68,33,80,46};//0号不存储有效数字
//        new HeapSort1().heapAdjust(nums,1, nums.length-1);
        //测试建立初始堆
        int[]nums={max,46,12,33,72,68,19,80,33};//0号不存储有效数字
//        new HeapSort1().createHeap(nums);
        //测试堆排序
        new HeapSort1().heapSort(nums);


        for (int i = 1; i < nums.length; i++) {
            System.out.print(nums[i]+"\t");
        }
        //80	72	68	46	33	33	19	12
    }

    //堆的筛选
    void heapAdjust(int[] nums,int s,int m){
        //已知nums[s..m]中记录的关键字除nums[s]之外均满足堆的定义
        //本函数调整nums[s]的关键字,是nums[s..m]成为一个小顶堆
        int t=nums[s];
        for (int j=2*s;j<=m;j*=2){
            //沿key较小的孩子结点向下筛选
            if (j<m&&nums[j]>nums[j+1]){
                j++;//j为key较小的记录的下标
            }
            if(t<=nums[j]){
                break;
            }
            //t应插入位置s
            nums[s]=nums[j];
            s=j;
        }
        nums[s]=t;
    }

    //建立初始堆
    void createHeap(int [] nums){
        int n=nums.length-1;//有效记录个数
        for (int i=n/2;i>=1;i--){
            heapAdjust(nums,i,n);
        }
    }

    //堆排序
    void heapSort(int [] nums){
        int n=nums.length-1;//有效记录个数
        createHeap(nums);
        for (int i=n;i>=2;i--){
            nums[0]=nums[1];
            nums[1]=nums[i];
            nums[i]=nums[0];
            heapAdjust(nums,1,i-1);
        }
    }


}

归并类排序

二路归并排序

自然归并排序

package sort1;

/**
 * @author CSDN@日星月云
 * @date 2022/10/30 22:25
 * 归并类排序
 */
public class MergeSort1 {
    public static void main(String[] args) {
        int[]nums={-1,1,2,3,4,5,0,9,8,7,6};//0号不存储有效数字
        //二路归并排序
//        int[] copy=new int[nums.length];
//        for (int i=0;i<nums.length;i++){
//            copy[i]=nums[i];
//        }
//        new MergeSort1().mergeSort(nums,copy,0,nums.length-1);
        //自然归并排序
        new MergeSort1().natureMergeSort(nums,nums.length);


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

    }

    //二路归并排序
    void mergeSort(int [] nums,int[] copy,int left,int right){
        //对上下限值分别为left和right的记录序列L进行归并排序
        //其中copy为同类型的记录,由于复制保存原记录序列
        int middle;
        if(left<right){
            middle=(left+right)/2;//找中间位置进行划分
            mergeSort(nums,copy,left,middle);//对左半部分进行递归归并排序
            mergeSort(nums,copy,middle+1,right);//对右半部分进行递归归并排序
            merge(nums,copy,left,right,middle);//进行归并

        }
    }

    void merge(int[] nums,int[] copy,int left,int right,int middle){
        int i,p1,p2;
        for (i=left;i<=right;i++){//用copy记录临时保存待排序记录序列
            copy[i]=nums[i];
        }
        p1=left;//左半部分有序记录的起始位置
        p2=middle+1;//右半部分有序记录的起始位置
        i=left;//左半部分开始进行归并
        while(p1<=middle&&p2<=right){
            //取两个有序半区中关键字较小的记录
            if (copy[p1]<=copy[p2]){
                nums[i]=copy[p1];//去较小的记录放到合并后的记录序列中
                p1++;
            } else{
                nums[i]=copy[p2];
                p2++;
            }
            i++;
        }
        //剩下的序列无论是左半部分还是右半部分都直接复制到合并后的记录序列中
        while (p1<=middle){
            nums[i]=copy[p1];
            i++;
            p1++;
        }
        while (p2<=middle){
            nums[i]=copy[p2];
            i++;
            p2++;
        }
    }

    //自然归并排序
    //将两个有序的子序列nums[low..m]和nums[m+1..high]归并成一个有序的子序列nums[low..high]
    void merge(int[]nums,int l,int m,int r){
        int i=l,j=m+1,p=0,q;
        int [] copy=new int[r-l+1];

        while (i<=m&&j<=r){
            //取两个有序半区中关键字较小的记录
            if(nums[i]<=nums[j]){
                copy[p++]=nums[i++];
            }else {
                copy[p++]=nums[j++];
            }
        }

        //剩下的序列无论是左半部分还是右半部分都直接复制到合并后的记录序列中
        if (i>m){
            for (q = j; q <=r ; q++) {
                copy[p++]=nums[q];
            }
        }else {
            for (q=i;q<=m;q++){
                copy[p++]=nums[q];
            }
        }

        for (p=0,i=l;i<=r;p++,i++){
            nums[i]=copy[p];//归并完成后将结果复制回R[low..high]
        }
    }
    void natureMergeSort(int[] nums,int n){
        int i,sum,low,mid,high;
        while (true){
            i=0;
            sum=1;
            while (i<n-1){
                low=i;
                while (i<n-1&&nums[i]<nums[i+1]){ i++; }
                mid=i++;
                while (i<n-1&&nums[i]<nums[i+1]){ i++; }
                high=i++;
                if (i<=n){
                    merge(nums,low,mid,high);
                    sum++;
                }
            }
            if (sum==1) break;
        }

    }



}

分配类排序

多关键字排序

链式基数排序

外部排序

置换选择排序

多路归并外排序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日星月云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值