【数据结构】复杂度-LMLPHP
🔥博客主页 小羊失眠啦.
🎥系列专栏《C语言》 《数据结构》 《Linux》《Cpolar》
❤️感谢大家点赞👍收藏⭐评论✍️


【数据结构】复杂度-LMLPHP

一、什么是数据结构


二、什么是算法


三、算法的效率


四、时间复杂度

4.1 时间复杂度的概念

void Func1(int N)
{
	int count = 0;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			++count;
		}
	}
	//N*N
	for (int k = 0; k < 2 * N; ++k)
	{
		++count;
	}
	//2*N
	int M = 10;
	while (M--)
	{
		++count;
	}
	//10
	printf("%d\n", count);
}

4.2 大O渐进表示法

推导大O阶方法:

另外有些算法的时间复杂度存在最好、平均和最坏情况:

  • 最坏情况:

    任意输入规模的最大运行次数(上界)

  • 平均情况:

    任意输入规模的期望运行次数

  • 最好情况:

    任意输入规模的最小运行次数(下界)

说明:在实际中一般情况关注的是算法的最坏运行情况。

4.2 常见时间复杂度计算

冒泡排序:

// 计算BubbleSort的时间复杂度?
void BubbleSort(int* a, int n)
{
	assert(a);
	for (int end = n; end > 0; --end)
	{
		int flag = 0;
		for (int i = 1; i < end; ++i)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				flag = 1;
			}
		}
		if (flag == 0)
			break;
	}
}

二分查找:

// 计算BinarySearch的时间复杂度?
int BinarySearch(int* a, int n, int x)
{
	assert(a);
	int left = 0;
	int right = n - 1;
	while (left <= right)
	{
		int mid = left + ((right - left) >> 1);
		if (a[mid] < x)
			left = mid + 1;
		else if (a[mid] > x)
			right = mid - 1;
		else
			return mid;
	}
	return -1;
}

O(N)和O(log2N)的对比:

由此我们看到O(log2N)相对O(N)在效率上有很大的提升,但二分查找有一个限制条件就是数组必须有序,所以在实际中二分查找应用并不多。

递归阶乘:

// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{
	if (0 == N)
		return 1;
 
	return Fac(N - 1) * N;
}

斐波那契数列:

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{
	if (N < 3)
		return 1;
 
	return Fib(N - 1) + Fib(N - 2);
}

4.3 例题:消失的数字

【数据结构】复杂度-LMLPHP

方法一:我们可以把0~N个数字全部加起来,减去数组中的元素,结果就是消失的数字。

时间复杂度为O(N)

int missingNumber(int* nums, int numsSize)
{
    int i=0;
    int ret=(numsSize+1)*numsSize/2;
    for(i=0;i<numsSize;i++)
    {
        ret-=nums[i];
    }
    return ret;
}

方法二: 我们可以使用异或,异或的条件是相同为0,相异为1。两个相同的数异或为0,0和任何数异或都为原数,所以我们将0~N与数组中的所有异或,得到的结果就是消失的数。

int missingNumber(int* nums, int numsSize){
    int i = 0,k = 0;
    for(i=0;i<numsSize;i++)
    {
        k^=nums[i];
    }
    for(i=0;i<numsSize+1;i++)
    {
        k^=i;
    }
    return k;
}

五、空间复杂度

空间复杂度的概念:

5.1 空间复杂度计算

冒泡排序:

void BubbleSort(int* a, int n)
{
	assert(a);
	for (size_t end = n; end > 0; --end)
	{
		int exchange = 0;
		for (size_t i = 1; i < end; ++i)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = 1;
			}
		}
		if (exchange == 0)
			break;
	}
}

递归阶乘:

// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{
 if(N == 0)
 return 1;
 
 return Fac(N-1)*N;
}

注意: 递归程序最大的问题就是深度太深,会有栈溢出的风险。

斐波那契数列:

long long Fib(size_t N)
{
 if(N < 3)
 return 1;
 
 return Fib(N-1) + Fib(N-2);
}

5.2 例题:轮转数组

【数据结构】复杂度-LMLPHP

方法一:右旋K次(每次右旋一次)【时间复杂度为O(N*K);空间复杂度为O(1)】(时间复杂度的k最大为N-1),最坏的结果为O(N^2))

方法二:开设一个新的数组,把后k个放到新数组的前面,前面的依次放到后面【时间复杂度O(N),空间复杂度O(N)】 (这种方法比第一种,就是时间换取空间的算法)

方法三:三趟逆置【时间复杂度为O(N),空间复杂度为O(1)】

void reverse(int*nums,int* left,int* right)
{
    int tmp=0;
    while(left<=right)
    {
        tmp=*left;
        *left=*right;
        *right=tmp;
        left++;
        right--;
    }
}
void rotate(int* nums, int numsSize, int k)
{
    k%=numsSize;
    int* p=nums;
    reverse(nums,p,p+numsSize-k-1);
    reverse(nums,p+numsSize-k,p+numsSize-1);
    reverse(nums,p,p+numsSize-1);
}

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位铁汁们的支持。文章有任何问题可以在评论区留言,小羊一定认真修改,写出更好的文章~~

【数据结构】复杂度-LMLPHP

10-30 21:49