数据结构与算法java实战篇--高级排序

目录

一.希尔排序

二.划分

 三.快速排序

1. 快速排序的算法

2.选择枢纽


一.希尔排序

希尔排序是基于插入排序的算法来实现的,不同的是希尔排序是采用n-增量来实现排序,如下是希尔排序的图解:

 希尔排序会先以n个增量对元素进行划分,并排序,然后再向后移动一个,在排序,然后缩小间隔n,循环如此直到元素有序

实现代码:

  class ArraySh{
    private long[] theArray;
    private int nElems;
    //初始化
    public ArraySh(int max){
        theArray=new long[max];
        nElems=0;
    }
    //插入操作
    public void insert(long value){
        theArray[nElems]=value;
        nElems++;
    }
    //显示操作
    public void display(){
        System.out.print("A=");
        for (int i=0;i<nElems;i++)
            System.out.print(theArray[i]+" ");
        System.out.println(" ");
    }
    //排序操作
        public void ShellSort(){
        int innter,outer;
        long temp;
        int h=1;
        while (h<=nElems/3)//间隔大于数组大小结束循环
            h=h*3+1; //whlie循环直到生成最大的间隔h
        while (h>0){ 
            for (outer=h;outer<nElems;outer++){
                temp=theArray[outer]; 
                innter=outer;
                while (innter>h-1&&theArray[innter-h]>=temp){  
                    theArray[innter]=theArray[innter-h];
                    innter-=h;
                }
                theArray[innter]=temp;
            }  //结束for循环
            h=(h-1)/3;
        }
    }
    }


二.划分

划分就是将数据按某个特定值分为两组,大于特定值的分为一组,小于特定值的分为一组,但划分后的数据还不是有序的

代码:

 class Arraypar{
    private long[] theArray;
    private int nElems;
    public Arraypar(int max){
        theArray=new long[max];
        nElems=0;
    }
    //插入操作
    public void insert(long value){
        theArray[nElems]=value;
        nElems++;
    }
    //元素个数
       public int size(){
        return nElems;
       }
       public void display(){
        System.out.print("A=");
        for(int i=0;i<nElems;i++){
            System.out.print(theArray[i]+" ");
        }
        System.out.println(" ");
       }
       //寻找特定值位置
       public int partitionIt(int left,int right,long pivot){
        int leftPtr=left-1;
        int rightPtr=right+1;
        while(true){
            while (left<right&&theArray[++leftPtr]<pivot);//找到比特定值小的
            while (right>left&&theArray[++rightPtr]>pivot);//找到比特定值大的
            if(leftPtr>=rightPtr) //查找完成
                break;
            else
                swap(leftPtr,rightPtr);
        }
        return leftPtr;
       }
       //swap方法
       public void swap(int dex1,int dex2){
        long temp;
        temp=theArray[dex1];
        theArray[dex1]=theArray[dex2];
        theArray[dex2]=temp;
       }
   }

例如:

A=149,192,47,152,159,195,66,61,17,167,118,64,27,80,30,105

特定值为90,在第8位,划分后:

A= 30,80,47,27,64,17,81,66,66,159,152,192,149,105


 三.快速排序

快速排序将元素按一个枢纽分为两组,一组大于枢纽,一组小于枢纽

1. 快速排序的算法

部分代码:

 public void recQuicSort(int left,int right){
        if(right-left<=0)
            return;
        else {
            int partition=paritionIt(left,right);
            recQuicSort(left,partition-1);   //左边子数组排序
            recQuicSort(partition+1,right);   //右边子数组排序
        }
    }

该算法有三个步骤:

1.按枢纽将元素分为左右两个子数组

2.调用自身对左边排序

3.调用自身对右边排序

4.左右排序后合并,完成元素的排序


2.选择枢纽

在对枢纽的选择时,枢纽可以是任意元素,为了方便,我们让枢纽为最右端的元素,然后对排序的算法加入选择枢纽操作:

代码:

 public void recQuicSort(int left,int right){
        if(right-left<=0)
            return;
        else {
                long piovt=theArray[right];  //枢纽
            int partition=paritionIt(left,right,piovt);
            recQuicSort(left,partition-1);   //左边子数组排序
            recQuicSort(partition+1,right);   //右边子数组排序
        }
    }

快速排序代码:

class ArrayIns{
    private long[] theArray;
    private int nElems;
    public ArrayIns(int max){
        theArray=new long[max];
        nElems=0;
    }
    //插入操作
    public void insert(long vallus){
        theArray[nElems]=vallus;
        nElems++;
    }
    //显示
    public void display(){
        System.out.print("A=");
        for(int i=0;i<nElems;i++)
            System.out.print(theArray[i]+" ");
        System.out.println(" ");
    }
    //快速排序
    public void QuickSort(){
        recQuickSort(0,nElems-1);
    }
    public void recQuickSort(int left,int right){
        if (right-left<=0)
            return;
        else {
          long pivot=theArray[right];
            int partitionIt=partitionIt(left,right,pivot);
            recQuickSort(left,partitionIt-1);
            recQuickSort(partitionIt+1,right);
        }
    }
    //枢纽操作
    public int partitionIt(int left,int right,long pivot){
        int leftptr=left-1;
        int rightptr=right;
        while (true){
            while (theArray[++leftptr]<pivot);
            while (theArray[--rightptr]>pivot&&rightptr>0);
            if (leftptr>rightptr)
                break;
            else
                swap(leftptr,rightptr);
        }
        swap(leftptr, Math.toIntExact(pivot));  //枢纽与第一组子数组最右边交换
        return leftptr;
    }
    //交换操作
    public void swap(int dex1,int dex2){
        long temp=theArray[dex1];
        theArray[dex1]=theArray[dex2];
        theArray[dex2]=temp;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

前段被迫创业

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

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

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

打赏作者

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

抵扣说明:

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

余额充值