【从零开始写博客】数组运用:二分查找和成员增删(day1)

代码随想录刷题60天

 


目录

数组概述(array)

一、数组的查找

暴力查找(枚举)

二分查找

二、数组的删改

使用快慢指针对数组元素进行增删

总结


 


数组概述(array)

数组作为一种数据结构,毫无疑问,其基本功能便是为程序员提供一种可增删查改的容器,本文将简要的从增删查改这一方面去介绍数组这一种数据结构。


 

一、数组的查找

暴力查找(枚举)

作为一种最基本的查找方式之一,其理解难度较低

int exhaustiveSearch(vector& nums, int target)
	{
		for (int i = 0; i < nums.size(); i++)
		{
			if (nums[i] == target)
				return i;
		}
		return -1;
	}

二分查找

二分查找这一查找方式是利用了被查找数组有序这一特点设计的,查找效率上要比暴力查找高。但在使用二分查找时,需要注意数组边界的开闭。

以下以左闭右闭区间为例:

我们的基本逻辑是将目标值与数组中间值进行比较:如果目标值等于中间值,则返回数组坐标;如果目标值大于中间值,则将数组的左界取为中间值的下一个元素;如果目标值大于中间值,则将数组右界取为中间值的上一个元素。具体实现代码如下:

    int binarySearch(vector& nums, int target)
	{
		if (!nums.size()||target target)
				pRight = pMiddle - 1;
			else if (nums[pMiddle] < target)
				pLeft = pMiddle + 1;
			else
				return pMiddle;
		}
		pMiddle = (pLeft + pRight) / 2;
		if (target == nums[pMiddle])
			return pMiddle;
		else
			return -1;
	}

通常情况下,我们在思考一中方法是否可行时,会去思考这种方法的大致实现方法,然后再去思考特例来判断该方法是否可行。如果该特例能够在代码实现过程中,通过添加特殊处理方式来处理掉,那么该方法是可实现的。如果不能,那么,该特例就将成为该方法不可使用的反例。因此,上述代码的实现中有几个点需要我们注意的。

1.当目标容器为空时,直接返回值。这样可以直接避免在取数组右界时造成下标越界这一错误。

2.当目标容器数组边界范围为1时,我们取的左界和右界相等,则不会进入循环。因此我们需要在循环外加一些额外代码来进行特殊情况的处理。

3.当我们在取中间值时,由于除法结果舍去小数来取整的性质,我们取得的中间值是偏小的。因此,在目标容器的边界范围为2的情况下,我们的中间值则会取为左界。当目标值小于中间值时,我们的右界将会取左界的左边,造成边界异常。同理,当我们将每次所取得中间值+1时,中间值偏大,当目标值大于中间值时,我们的左界将取右界的右边,也造成边界异常。

当然,为了规避以上问题,我们可以将代码进行优化,具体如下:

    int binarySearch(vector& nums, int target)
	{
		if (!nums.size())return -1;

		int pLeft=0, pRight=nums.size()-1;//左闭右闭
		int pMiddle;
		while (pLeft <= pRight)
		{
			pMiddle = (pLeft + pRight) / 2;
			
			if (nums[pMiddle] > target)
				pRight = pMiddle - 1;
			else if (nums[pMiddle] < target)
				pLeft = pMiddle + 1;
			else
				return pMiddle;
		}
		return -1;
	}

由此可见,在二叉查找问题中,数组边界问题的讨论,显得尤为重要。

二、数组的删改

使用快慢指针对数组元素进行增删

在对数组进行增删操作时,由于数组的地址是连续的,所以不能对数组中某个元素地址进行删除或向数组某个位置进行数组插入一段带有数据的地址。因此在对数据进行增删操作时,采取的是覆盖。而如果采取覆盖这一手段,则修改某一个数据就要对之后每一个数据进行迁移操作,在面对较多数据时,这样操作的时间复杂度较大,所以我们选取了一种更为方便的手段来对增删数组中元素——快慢指针。

详细代码如下:

    int removeElement(int* nums, int numsSize, int val) 
    {
		int pSlow=0;
		for (int pFast = 0; pFast < numsSize; pFast++)
		{
			if (nums[pFast] != val)
				nums[pSlow++] = nums[pFast];
		}
		return pSlow;
	}

总结

数组作为一种基本的数据结构,其基本功能便是增删查改,而使用合适的方法进行该操作,不仅能大幅减少代码的复杂程度,还能提高增加代码的可读性。

 

 

你可能感兴趣的:(算法,c++)