查找与排序

C++查找与排序

排序

希尔排序

希尔排序是插入排序的改进,其中最里层循环其实就是插入排序
核心思想:增量缩小排序,设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入排序。然后缩小间隔increment,重复上述子序列划分和排序工作。直到最后取increment=1,将所有元素放在同一个子序列中排序为止。
由于开始时,increment的取值较大,每个子序列中的元素较少,排序速度较快,到排序后期increment取值逐渐变小,子序列中元素个数逐渐增多,但由于前面工作的基础,大多数元素已经基本有序,所以排序速度仍然很快。
以下代码我加入了一些解释的注释以便读者更好的理解

int shell_sort(int *data, int length){
	int gap = 0;
	int i =0, j = 0;
	int temp = 0;
	///第一个for循环为分组的过程
	for(gap = length/2; gap >= 1; gap /=2){
	///第二个for循环为逐个组遍历
		for(i = gap; i < length; i++){
			temp = data[i];
			///第三个for循环为组内进行插入排序,其实就是讲temp也就是data[i]插入进去
			for (j = i-gap; j >= 0 && temp < data[j]; j = j - gap){
				///插入的方式就是,不停的往后挪一个gap,直到temp比前面的大,比后面的小
				data[j+gap] = data[j];
			}
			///此行就是把temp给插入到正确位置
			data[j+gap] = temp;
		}
	}
}

归并排序

递归的方式


void merge_sort(int *arr, int left, int right)
{
	if (left == right)
	return;
	int mid = (left + right) / 2;
	merge_sort(arr, left, mid);
	merge_sort(arr, mid+1, right);
	merge(arr, left, mid, right);
}
void merge(int *arr, int left, int mid, int right)
{
	int n = right - left + 1;
	int *temp = new int[n]; 
	int i = 0;
	int lefttmp = left;
	int righttmp = mid + 1;
	while(lefttmp <= mid && rightmp <= right)
	{
		temp[i++] = arr[lefttmp] < arr[righttmp] ? arr[lefttmp++]:arr[righttmp++];
	}
	while(lefttmp <= mid)
	{
		temp[i++] = arr[lefttmp++];
	}
	while(righttmp <= right)
	{
		temp[i++] = arr[righttmp++];
	}
	for(int j = left; j <= right; j++)
	{
		arr[j] = temp[j-left];
	}
}

快速排序

快速排序采用思想为分而治之
基本思想:首先选择一个数作为哨兵,即基准数。然后,将整个数组比这个哨兵大的放在右边,小的放在左边。
最后将哨兵两侧的数据重复上述过程。

具体代码实现:
选择哨兵,我们一般直接取数组第一个数作为基准数,然后开始排序
具体排序方法如下,也是算法的核心逻辑:
1.选择基准后,保存为临时变量。
2.从右侧开始于基准比较直到数据比基准小,那么将这个比基准小的数据挪到基准的位置,那么当前位置则空了出来(不用担心基准数值被覆盖,我们以前保存到了临时变量)。然后再从左侧开始向右查找,直到遇到比基准大的数字,然后将这个数字放到上轮空出的位置。然后再从右侧继续查找,循环的去填补空位,当左右都查找到了一个相同的位置,那么这个位置就是最终要填补的空位,这个空位左侧都比基准小,右侧都比基准打。没错,这个空位就给最开始基准临时变量保留的。
3.这样我们就完成了第一轮快排,然后我们将基准左侧与右侧分别继续进行快排。左侧的快排和右侧的快排里面又会继续分组快排,我们知道 递归很重要的一点是知道什么时候停下,在此处,不难发现,当递归的数组长度只有1时,无需递归,直接返回。

int quick_sort(int *arr, int start, int end)
{
	int i = start, j = end;
	if (i >= j)
	{
		return;
	}
	///保存基准
	int temp = arr[i];
	while(i != j)
	{
		while((i < j) && (arr[j] > temp))
		{
			j--;
		}
		if (i < j)
		{
			arr[i] = arr[j];
		}
		while((i < j) && (arr[i] < temp))
		{
		 	i++;
		}
		if (i < j)
		{
			arr[j] = arr[i];
		}
	}
	///放入最后的基准
	arr[i] = temp;
	///左右分别进行快速排序
	quick_sort(arr, start, i-1);
	quick_sort(arr, i+1, end);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值