快速排序算法(Partition函数)分析与拓展

零、前言——二分查找       

            条件:如果数组是有序数组、部分有序数组、或者局部有序数组,在这类数组中进行查找时,二分查找较为常用。时间复杂度O(logN)。二分查找的主要思路:设定两个指针start和end分别指向数组元素的首、尾,然后比较数组中间结点arry[mid]和待查找元素。如果待查找元素小于中间元素,说明待查找元素在数组的前半段,那么将end=mid-1,如果待查找元素大于中间元素,说明该元素在数组的后半段,将start=mid+1; 如果中间元素等于待查找元素,那么返回mid的值。

//统计一个数字在已经有序的数组中出现的次数。
int binary_search(vector<int> data, int len, int goal)
{
	int low = 0;
	int high = len - 1;
	while (low <= high)
	{
		int middle = (high - low) / 2 + low;    // 直接使用(high + low) / 2 可能导致溢出
		if (data[middle] == goal)
			return middle;

		//在左半边
		else if (data[middle] > goal)
			high = middle - 1;

		//在右半边
		else
			low = middle + 1;
	}
	//没找到
	return -1;
}

int GetNumberOfK(vector<int> data, int k) 
{
	int count = 0;
	int index;
	int len = data.size();
	index = binary_search(data, len, k);
	if (index != -1)
	{
		count++;
		for (int i = index - 1; i >= 0; i--)
		{
			if (data[i] == k)
			{
				count++;
			}
		}
		for (int i = index + 1; i < len; i++)
		{
			if (data[i] == k)
			{
				count++;
			}
		}
	}
	return count;
}

void main()
{
	vector<int> v = { 1, 2, 3, 3, 3, 3, 3, 3, 4, 5 };
	cout << GetNumberOfK(v, 3);
}

//寻找第一个
int getFirstTarget(vector<int>& data, int target)
{
    int length = data.size();
    if (length <= 0)
    {
        return -1;
    }

    int pLeft = 0;
    int pRight = length - 1;

    while (pLeft <= pRight)
    {
        int index = (pLeft + pRight) / 2;
        if (data[index] == target)
        {
            if ((index > 0 && data[index - 1] != target) || index == 0)    //限制得到的是第一个target数字
            {
                return index;
            }
            else  
                pRight = index - 1;
        }
        else if (data[index] < target)
        { 
            pLeft = index + 1; 
        }
        else  
        { 
            pRight = index - 1; 
        }
    }
    return -1;
}

//寻找最后一个
int getLastTarget(vector<int>& data, int target)
{
    int length = data.size();
    if (length <= 0)
    {
        return -1;
    }

    int pLeft = 0;
    int pRi
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值