插入排序和交换两个数方法

目录

插入排序

基本思想

算法描述

代码实现

①. 移位法:

②. 交换法:

算法效率

交换两个数方法

临时变量

算术法交换

位运算交换  

参考代码


直接插入排序

基本思想

直接插入排序的基本思想是:将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过为止。

算法描述

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

①. 从第一个元素开始,该元素可以认为已经被排序

②. 取出下一个元素,在已经排序的元素序列中从后向前扫描

③. 如果该元素(已排序)大于新元素,将该元素移到下一位置

④. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

⑤. 将新元素插入到该位置后

⑥. 重复步骤②~⑤

代码实现

提供两种写法,一种是移位法,一种是交换法。移位法是完全按照以上算法描述实,再插入过程中将有序序列中比待插入数字大的数据向后移动,由于移动时会覆盖待插入数据,所以需要额外的临时变量保存待插入数据,代码实现如下:

①. 移位法:

public static void sort(int[] a) {
        if (a == null || a.length == 0) {
            return;
        }
        for (int i = 1; i < a.length; i++) {
            int j = i - 1;
            // 先取出待插入数据保存,因为向后移位过程中会把覆盖掉待插入数
            int temp = a[i]; 
            // 如果待是比待插入数据大,就后移
            while (j >= 0 && a[j] > temp) { 
                a[j+1] = a[j];
                j--;
            }
            // 找到比待插入数据小的位置,将待插入数据插入
            a[j+1] = temp; 
        }
    }

而交换法不需求额外的保存待插入数据,通过不停的向前交换带插入数据,类似冒泡法,直到找到比它小的值,也就是待插入数据找到了自己的位置。

②. 交换法:

  public static void sort2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        for (int i = 1; i < arr.length; i ++) {
            int j = i - 1;
            while (j >= 0 && arr[j] > arr[i]) {
                 //只要大就交换操作
                arr[j + 1] = arr[j] + arr[j+1];     
                arr[j] = arr[j + 1] - arr[j];
                arr[j + 1] = arr[j + 1] - arr[j];
            }
        }
    }

算法效率

直接插入排序不是稳定的排序算法。

平均时间复杂度最好情况最坏情况空间复杂度
O(n2)O(n)O(n2)O(1)


 

交换两个数方法

临时变量

  思路简介:建立一个临时变量,通过temp=a,a=b,b=temp来实现交换。

   缺点:这只是一种假交换,由于这只是在函数内部临时变量间的交换,所以当函数退出,函数栈帧被释放,原本的值并没有交换。

    /**
     * 临时变量法(引入一个中间值)
     *
     * @param a 1
     * @param b 2
     */
    private static void swapByTemp(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        // 2|1
        System.out.println(" 临时变量法 交换后: 1--" + a + "|" + b);
    }

算术法交换

思路简介:取两个数的和,然后通过减去另外一个数来得到这个数。

方法缺陷:两个数的和可能会越界。(数值小的时候可以用)。同样的这是一种假交换,函数调用结束后原本的值并没有真正的交换。

/**
     * 通过算术法交换(可能溢出)
     *
     * @param a 110
     * @param b 200
     */
    private static void swapByArithmetic(int a, int b) {
        // a == a + b  310
         a = a + b;
        // b== a + b - b == a, 此时b == a    310-200
        b = a - b;
        // a == a + b - a == b, 此时a == b   310-110
        a = a - b;
        System.out.println(" 通过算术法交换 交换后:" + a + "|" + b);
    }

位运算交换  

思路简介:通过二进制异或方法交换

/**
     * 位运算
     *
     * @param a
     * @param b
     */
    private static void swapByBitOperation(int a, int b) {
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;
        // 0|2
        System.out.println(" 位运算 交换后:" + a + "|" + b);
    }
}

参考代码


public class TwoNumberSwap {
    public static void main(String[] args) {
        int a = 110;
        int b = 200;
        System.out.println("1.临时变量法 交换前:    " + a + "|" + b);
        swapByTemp(a, b);
        // 1|2(没有返回值还是以前的a、b)
        System.out.println(" 临时变量法 交换后 :2--" + a + "|" + b);

        int one = 2;
        int two = 0;
        //2|0
        System.out.println("2.通过算术法交换 交换前:" + one + "|" + two);
        swapByArithmetic(one, two);

        int x = 110;
        int y = 200;
        System.out.println("3.位运算 交换前:" + x + "|" + y);
        swapByBitOperation(a, b);
    }

    /**
     * 临时变量法(引入一个中间值)
     *
     * @param a
     * @param b
     */
    private static void swapByTemp(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        // 2|1
        System.out.println(" 临时变量法 交换后: 1--" + a + "|" + b);
    }

    /**
     * 通过算术法交换(可能溢出)
     *
     * @param a
     * @param b
     */
    private static void swapByArithmetic(int a, int b) {
        // a == a + b 310
        a = a + b;
        // b== a + b - b == a, 此时b == a   310-200
        b = a - b;
        // a == a + b - a == b, 此时a == b   310-110
        a = a - b;
        System.out.println(" 通过算术法交换 交换后:" + a + "|" + b);
    }

    /**
     * 位运算
     *
     * @param a
     * @param b
     */
    private static void swapByBitOperation(int a, int b) {
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;
        // 0|2
        System.out.println(" 位运算 交换后:" + a + "|" + b);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

what_2018

你的鼓励是我前进的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值