插入排序、折半排序、2路排序

本文介绍了三种不同的插入排序算法:基本插入排序、折半插入排序和2路插入排序,并提供了详细的实现代码。通过这些算法的学习,读者可以更好地理解排序算法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插入排序

public void basicInsert(){
        // 0~i-1 已经有序,插入第i个数据
        for(int i=1;i<len;i++){
            int key = array[i];
            int j;
            //找到位置j,使得 array[j-1] < key < array[j],key 插入到 array[j]
            //注意 j>0 要写在 array[j-1]>key 前面,否则数组越界直接报错
            for( j = i ;j>0&&array[j-1]>key ;j--){
                array[j]=array[j-1];
            }
            array[j]=key;

        }

    }

折半排序

public void binaryInsert() {

        for (int i = 1; i < len; i++) {
            int start = 0, end = i - 1, mid = (start + end) / 2;
            //第 0 ~ i-1 有序,找到合适的位置start插入array[i]
            int key = array[i];
            while (start <= end) {
                if (key > array[mid]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
                mid = (start + end) / 2;
            }
            for (int j = i; j > start; j--) {
                array[j] = array[j - 1];
            }
            array[start] = key;
        }
    }

2路排序

public void twoRoadInsert(){

        int[] tmp = new int[len];
        tmp[0] = array[0];
        int max= 0 ,min=0;//始终为tmp中最大、最小数的下标
        for(int i=1;i<array.length;i++){
            if(array[i]>tmp[max]){
                max++;
                tmp[max] = array[i];
            }else if (array[i]<tmp[min]){
                min = (min-1+len) % len ;
                tmp[min]  = array[i];
            }else{
                //在最大值和最小值之间,且大于参照值,
                // 4  7  8<-max         1<-min  3  , eg: 5
                if(array[i]>tmp[0]){
                    int curIndex = max;
                    max++;
                    while(array[i]<tmp[curIndex]){
                        tmp[curIndex+1] = tmp[curIndex];
                        curIndex--;
                    }
                    tmp[curIndex+1] = array[i];

                }else{//小于参照值
                    int curIndex = min;
                    min = (min-1+len) % len ;
                    //比array[i] 小的 前移一位
                    do{

                        tmp[(curIndex-1+len)%len] = tmp[curIndex];
                        curIndex=(curIndex-1+len)% len;
                    }while (tmp[curIndex]<array[i]);
                    tmp[(curIndex-1+len) % len ] = array[i];

                }
            }

        }
        int j =0 ;
        for(int p = min;j<len;j++,p=(p+1)%len){
            array[j] = tmp[p];
        }
    }

全部代码

package algorihtm;
/*
从小到大排序
简单插入排序
折半插入排序
2路插入排序
 */
public class InsertSort {
    private int[] array;
    private int len;

    public InsertSort(int[] data){
        array = data;
        len=array.length;
    }

    public void diplay(){
        for (int i: array ) {
            System.out.print(i+" ");
        }
        System.out.println();
    }

    public void basicInsert(){
        // 0~i-1 已经有序,插入第i个数据
        for(int i=1;i<len;i++){
            int key = array[i];
            int j;
            //找到位置j,使得 array[j-1] < key < array[j],key 插入到 array[j]
            //注意 j>0 要写在 array[j-1]>key 前面,否则数组越界直接报错
            for( j = i ;j>0&&array[j-1]>key ;j--){
                array[j]=array[j-1];
            }
            array[j]=key;

        }

    }

    public void binaryInsert() {

        for (int i = 1; i < len; i++) {
            int start = 0, end = i - 1, mid = (start + end) / 2;
            //第 0 ~ i-1 有序,找到合适的位置start插入array[i]
            int key = array[i];
            while (start <= end) {
                if (key > array[mid]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
                mid = (start + end) / 2;
            }
            for (int j = i; j > start; j--) {
                array[j] = array[j - 1];
            }
            array[start] = key;
        }
    }

    //2-路插入排序
    /*
      4 5 6<-max         1<-min 2
     */
    public void twoRoadInsert(){

        int[] tmp = new int[len];
        tmp[0] = array[0];
        int max= 0 ,min=0;//始终为tmp中最大、最小数的下标
        for(int i=1;i<array.length;i++){
            if(array[i]>tmp[max]){
                max++;
                tmp[max] = array[i];
            }else if (array[i]<tmp[min]){
                min = (min-1+len) % len ;
                tmp[min]  = array[i];
            }else{
                //在最大值和最小值之间,且大于参照值,
                // 4  7  8<-max         1<-min  3  , eg: 5
                if(array[i]>tmp[0]){
                    int curIndex = max;
                    max++;
                    while(array[i]<tmp[curIndex]){
                        tmp[curIndex+1] = tmp[curIndex];
                        curIndex--;
                    }
                    tmp[curIndex+1] = array[i];

                }else{//小于参照值
                    int curIndex = min;
                    min = (min-1+len) % len ;
                    //比array[i] 小的 前移一位
                    do{

                        tmp[(curIndex-1+len)%len] = tmp[curIndex];
                        curIndex=(curIndex-1+len)% len;
                    }while (tmp[curIndex]<array[i]);
                    tmp[(curIndex-1+len) % len ] = array[i];

                }
            }

        }
        int j =0 ;
        for(int p = min;j<len;j++,p=(p+1)%len){
            array[j] = tmp[p];
        }
    }



    public static void main(String[] args){
        int[] data = new int[] {3,12,4,1,33,0,111};
        InsertSort obj = new InsertSort(data);
        obj.diplay();
        //obj.basicInsert();
        //obj.binaryInsert();
        obj.twoRoadInsert();
        obj.diplay();
    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值