常见排序算法流程分析及其实现代码(二)

112 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

折半插入排序

1、执行流程

在这个排序算法中,我们会设置四个辅助变量:low,high,mid,temp。

low用来标志待插入有序序列中最小的元素的下标
high用来标志待插入有序序列中最大的元素的下标
mid即为low与high之间最中间的元素的下标,计算方法为(low+high)/2向下取整。
temp用来标志待排元素的下标

每趟排序low初始定义为0,high定义为已排好序序列的最大元素的下标,temp定义为high+1,比较下标为mid和下标为temp所在元素的大小

当temp<mid时,high=mid-1,low不变,重新计算mid,继续比较
当temp>mid时,low=mid+1,high不变,重新计算mid,继续比较
当low>high时停止比较,得出待排元素应插入的位置

原始序列:49 38 65 97 76 13 27 49 (序列中有两个49,其中一个加粗加以区分并可以验证该排序算法稳定性)

1)首先看49,直接放入有序序列中

  49   38 65 97 76 13 27 49

2)计算38应插入的位置

low=0;high=0;mid=(0+0)/2=0;temp=38 38<49,high=mid-1=-1,此时low>high,停止比较,即38应插入到49之前

  38 49   65 97 76 13 27 49

3)计算65应插入的位置

low=0;high=1;mid=(0+1)/2=0;temp=65 65>38,low=mid+1=1,low<high,继续比较,mid=(1+1)/2=1 65>49,low=mid+1=2,low>high,停止比较,即65应插入到49之后

  38 49 65  97 76 13 27 49

4)计算97应插入的位置

同理可得

  38 49 65 97  76 13 27 49

5)计算76应插入的位置

low=0;high=3;mid=(0+3)/2=1;temp=76 76>49,low=mid+1=2,mid=(2+3)/2=2 76>65,low=mid+1=3,mid=(3+3)/2=3 76<97,high=mid-1=2,此时low>high,停止比较,即76应插入到97之前

  38 49 65 76 97  13 27 49

剩余比较步骤省略

2、执行代码

public class BinarySort {

	public static void sort(int num[], int n) {
		int i, j, k, low, mid, high, temp;
		for(i = 1; i < n; i++) {
			low = 0;
			high = i - 1;
			temp = num[i];
			while(low <= high) {
				mid = (low + high) / 2;
				if(temp < num[mid]) {
					high = mid - 1;
				}else {
					low = mid + 1;
				}
			}
			for(j = i - 1; j >= high + 1; j--) {
				num[j+1] = num[j];
			}
			num[j+1] = temp;
			System.out.print("第"+i+"趟:");
			for(k = 0; k < num.length; k++) {
				System.out.print(num[k] + " ");
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		int mynum[] = {49, 38, 65, 97, 76, 13, 27, 49};
		sort(mynum, mynum.length);
	}
}

20200831111906436.png

3、性能分析

时间复杂度:O(n^2^) 空间复杂度:O(1) 稳定性:稳定