笔记:插入排序(直接插入排序、折半插入排序、2路插入排序、希尔排序)

1.直接插入排序

//插入排序(直接插入)
void INSERTsort(int* arr, int len) {
	for (int i = 1; i < len; i++) {
		for (int j = i - 1; j >= 0; j--) {   //第pass趟排序后,前pass-1个序列有序但非最小
			if (arr[j] <= arr[j + 1]) 
				break;                 //找到正确插入的位置后停止继续往前遍历比较
			swap(arr[j], arr[j + 1]);
		}
		// display(arr, len); //打印第pass趟的结果
	}
}

2. 折半插入排序

//插入排序(折半插入)
int Binfind(int key, int* A, int low, int high) {
	while (low <= high) {
		int mid = (low + high) / 2;
		if (key > A[mid])
			low = mid + 1;
		else
			high = mid - 1;
	}
	return high+1;   //返回high+1为key的正确插入位置(即a[0]~a[high]都小于key,a[high+1]~a[len-1]都大于key)
}
void BinINSERTsort(int* arr, int len){
	for (int i = 1; i < len; i++) {
		int key = arr[i];
		int h = Binfind(key, arr, 0, i-1);
		for (int j = i; j > h; j--) {   //a[high+1]~a[i-1]后移
			arr[j] = arr[j - 1];
		}
		arr[h] = key;  //key插入到指定位置
		// display(arr, len);  //打印第pass趟的结果
	}
}

3. 2路插入排序

//2路插入排序
int Binfind(int key, int* A, int low, int high) {
	while (low <= high) {
		int mid = (low + high) / 2;
		if (key > A[mid])
			low = mid + 1;
		else
			high = mid - 1;
	}
	return high+1;   //返回high+1为key的正确插入位置(即a[0]~a[high]都小于key,a[high+1]~a[len-1]都大于key)
}
void TwoPassINSERTsort(int* arr, int len) {
	int* A = new int[len];
	for (int i = 1; i < len; i++)
		A[i] = 0;
	A[0] = arr[0];
	int first = len, final = 0;
	for (int i = 1; i < len; i++) {
		//往A[0]后的有序序列折半插入,final后移
		if (arr[i] > A[0]) {
			int h = Binfind(arr[i],A,1,final);
			for (int j = final + 1; j > h; j--) {
				A[j] = A[j - 1];
			}
			A[h] = arr[i];
			final++;
		}
		//往A[0]前的有序序列折半插入,first前移
		else {
			int h = Binfind(arr[i], A, first, len - 1)-1;
			for (int j = first - 1; j < h; j++) {
				A[j] = A[j + 1];
			}
			A[h] = arr[i];
			first--;
		}
		// display(A, len);//打印第pass趟的结果
	}
	//将A拷贝到arr(从first开始)
	for (int i = 0; i < len; i++) {
		arr[i] = A[int((i + first) % len)];
	}
	// display(arr, len); //打印排序结果
}

4. 希尔排序

//希尔排序
void Shellsort(int* arr, int len) {
	int hlen = 4;
	int h[4] = {1,2,3,5};  //设置增量序列
	for (int i = hlen - 1; i >= 0; i--) {
		//每趟希尔排序结果
		for (int j = 0; j < h[i]; j++) {
			//每个子序列使用直接插入排序
			for (int k = j + h[i]; k < len; k += h[i]) {
				for (int m = k - h[i]; m >= j; m -= h[i]) {
					if (arr[m] > arr[m + h[i]]) {
						swap(arr[m] , arr[m + h[i]]);
					}
				}
			}
			display(arr, len);
		}
		std::cout << "\n";
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值