快排以及利用快排进行查重

// BinarySearchFindDistinct.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/**
* 可查找重复元素的二分查找算法
* 思路:
* 	1、先定义两个下标 , left = 0 , right = arr.length -1;
* 	2、因为我们也不知道要循环多少次,定义一个while循环,终止条件为right>left
* 	3、因为是二分查找,定义一个mid = left + (right - left) / 2;防止数据过大溢出
* 	4、定义三个if语句,如果 target == arr[mid], return mid;这是经典的二分查找,我们需要在这做改进
* 	4.1、改进经典二分算法,因为可能有重复元素,我们需要返回第一个出现target的下标;因为我们也不知道mid前面有几个重复的元素
* 因此我们需要一个while(mid>=0)的循环,mid--,然后比对arr[mid]和target,只要不一样就终止,返回
* 	5、如果 target < arr[mid] , right = mid - 1;
* 	6、如果target > arr[mid] , left = mid + 1;
* @param nums
* @param target
* @return
*/
//static int binarySearch(int []nums, int target){
static int binarySearch(int nums[10], int target){

	int left = 0;
	//int right = nums.length - 1;
	int right = 10 - 1;

	while (left <= right) {
		int mid = (left + (right - left) / 2);
		if (target == nums[mid]) {
			while (mid >= 0) {
				if (nums[mid] != target) {
					break;
				}
				mid--;
			}
			if (mid <= -1) {
				return 0;
			}
			return mid + 1;//多减了一次,返回的时候需要再加1
		}
		else if (target < nums[mid]) {
			right = mid - 1;
		}
		else {
			left = mid + 1;
		}
	}

	return -1;
}

int a[101], n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right) {
	int i, j, t, temp;
	if (left > right)
		return;
	temp = a[left]; //temp中存的就是基准数
	i = left;
	j = right;
	while (i != j) { //顺序很重要,要先从右边开始找
		while (a[j] >= temp && i < j)
			j--;
		while (a[i] <= temp && i < j)//再找右边的
			i++;
		if (i < j)//交换两个数在数组中的位置
		{
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
	//最终将基准数归位
	a[left] = a[i];
	a[i] = temp;
	quicksort(left, i - 1);//继续处理左边的,这里是一个递归的过程
	quicksort(i + 1, right);//继续处理右边的 ,这里是一个递归的过程
}

int _tmain(int argc, _TCHAR* argv[])
{
	//-- 查找重复元素,前提是此数据序列 是有序的
	int nums[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 8, 10 };
	binarySearch(nums, 8);




	//-- 快排
	int i;
	//读入数据
	scanf_s("%d", &n);
	for (i = 1; i <= n; i++)
		scanf_s("%d", &a[i]);
	quicksort(1, n); //快速排序调用
	//输出排序后的结果
	for (i = 1; i < n; i++)
		printf("%d ", a[i]);
	printf("%d\n", a[n]);

	return 0;
}

//-- 另一个讲述快排的, https://blog.csdn.net/pengzonglu7292/article/details/84938910
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值