Insertionsort

经典插入排序

  • 具体算法:

在数组中向前遍历每个元素,遍历时将这个元素插入到前面的序列中。

//代码清单:
	//in java source code
	 for (int i = left, j = i; i < right; j = ++i) {
        long ai = a[i + 1];
        while (ai < a[j]) {
            a[j + 1] = a[j];
            if (j-- == left) {
                break;
            }
        }
        a[j + 1] = ai;
     }

双点插入排序

向前遍历时每次遍历两个元素,两个元素先拍好次序,当较小的元素找到位置后,较大的元素在该位置之后查找位置,减少了第二个元素从头到尾注意比较的开销

//代码清单:
	//in java source code
	do {
        if (left >= right) {
            return;
        }
        } while (a[++left] >= a[left - 1]);

        for (int k = left; ++left <= right; k = ++left) {
            long a1 = a[k], a2 = a[left];

            if (a1 < a2) {
                a2 = a1; a1 = a[left];
            }
            while (a1 < a[--k]) {
                a[k + 2] = a[k];
            }
            a[++k + 1] = a1;

            while (a2 < a[--k]) {
                a[k + 1] = a[k];
            }
            a[k + 1] = a2;
        }

		//由于是双点插入,一旦数组的长度是奇数,最后一个元素将没办法执行上面的for语句,因此需要对最后一个元素进行简单排序
        long last = a[right];

        while (last < a[--right]) {
            a[right + 1] = a[right];
        }
        a[right + 1] = last;
    }

二分插入排序:java.util.TimSort.binarySort

lo是需要排序的序列的起始索引号,hi是终止索引号,start是即将新插入的元素的索引号所以轴p为a[start],一开始的时候,left指向lo,right指向hi,mid=(left+right)/2,如果a[mid]<p,则交换。否则left++之后重新计算mid,再进行计算。该排序方法是稳定的。

		private static <T> void binarySort(T[] a, int lo, int hi, int start,
	                                       Comparator<? super T> c) {
	        assert lo <= start && start <= hi;
	        if (start == lo)
	            start++;
	        for ( ; start < hi; start++) {
	            T pivot = a[start];
	
	            // Set left (and right) to the index where a[start] (pivot) belongs
	            int left = lo;
	            int right = start;
	            assert left <= right;
	            /*
	             * Invariants:
	             *   pivot >= all in [lo, left).
	             *   pivot <  all in [right, start).
	             */
	            while (left < right) {
	                int mid = (left + right) >>> 1;
	                if (c.compare(pivot, a[mid]) < 0)
	                    right = mid;
	                else
	                    left = mid + 1;
	            }
	            assert left == right;
	
	            int n = start - left;  // The number of elements to move
	            // Switch is just an optimization for arraycopy in default case
	            switch (n) {
	                case 2:  a[left + 2] = a[left + 1];
	                case 1:  a[left + 1] = a[left];
	                         break;
	                default: System.arraycopy(a, left, a, left + 1, n);
	            }
	            a[left] = pivot;
	        }
	    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值