C++——算法基础之排序——希尔排序(已修改)

这一节我们来聊一聊希尔排序!

希尔排序:按 dk 把序列分成若干子序列,先排子序列,再随着 dk 的减小合并排列。

教科书:希尔排序是插入排序的一种,其代码也难以理解;在要排序的序列中留下第 0 位用于临时储存元素。然后使 dk 按照某种方式逐渐减小直至为 1,完成排序。


(以下发现仅供参考)

本人:我更认为希尔排序是交换排序的一种,而且写出来的代码也易于理解,在要排序的序列中无需留下空间。

在循环次数上还有待提升。




#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <functional>
#include <algorithm>
#include <numeric>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <conio.h>
using namespace std;

#define N 10


//交换排序   希尔排序
void shellSortFalse1 (int *a, int n, int &flag)	//flag为交换次数
{
	int mark = 0;
	for(int data = n / 2; data >= 1; data /= 2)
	{
		bool completeSort = false;
		bool getTwoMax = false;
		for(int i = data; i < n && (!completeSort); i++)
		{
			completeSort = true;
			for(int j = 0; j < (n - i); j++)
			{
				mark++;
				getTwoMax = true;
				if(a[j] > a[j + data])
				{
					flag++;
					int temp = a[j];
					a[j] = a[j + data];
					a[j + data] = temp;
					completeSort = false;
					getTwoMax = false;
				}
			}
			if(getTwoMax)
			{
				i++;
			}
		}

		cout << "shellSortFalse1:";
		for(int i = 0; i < n; i++)
		{
			cout << "  " << a[i];
		}
		cout << endl << endl;
	}
	cout << "循环:" << mark << " 交换:" << flag << endl;
}

//交换排序   希尔排序
void shellSortFalse2 (int *a, int n, int &flag)	//flag为交换次数
{
	int mark = 0;
	for(int data = n / 2; data >= 1; data /= 2)
	{
		for(int i = data; i < n; i++)
		{
			for(int j = 0; j < (n - i); j++)
			{
				mark++;
				if(a[j] > a[j + data])
				{
					flag++;
					int temp = a[j];
					a[j] = a[j + data];
					a[j + data] = temp;
				}
			}
		}

		cout << "shellSortFalse2:";
		for(int i = 0; i < n; i++)
		{
			cout << "  " << a[i];
		}
		cout << endl << endl;
	}
	cout << "循环:" << mark << " 交换:" << flag << endl;
}


//插入排序   希尔排序
void shellSortTrue (int *p, int n, int &flag)		//falg为插入次数
{
	int mark = 0;
	int i, j;
	for(int dk = (n - 1) / 2; dk >= 1; dk /= 2)
	{
		for(i = dk + 1; i < n; i++)
		{
			if(p[i] < p[i - dk])
			{
				p[0] = p[i];
				for(j = i - dk; j > 0 && (p[0] < p[j]); j = j - dk)
				{
					mark++;
					flag++;
					p[j + dk] = p[j];
				}
				p[j + dk] = p[0];
			}
		}
		cout << "shellSortTrue:";
		for(int i = 1; i < 21; i++)
		{
			cout << "  " << p[i];
		}
		cout << endl << endl;
	}
	cout << "循环:" << mark << " 交换:" << flag << endl;
}


int main ()
{
	int a1[] = { 88, 6, 3, 8, 9, 8, 99, 11, 55, 66, 45, 69, 5, 2, 0, 7, 4, 1, 63, 23 };
	int flag1 = 0;
	shellSortFalse1 (a1, 20, flag1);
	cout << endl << endl;

	int a2[] = { -1, 88, 6, 3, 8, 9, 8, 99, 11, 55, 66, 45, 69, 5, 2, 0, 7, 4, 1, 63, 23 };
	int flag2 = 0;
	shellSortTrue (a2, 21, flag2);
	cout << endl << endl;


	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值