[Data Structure] Complexity Explanation

Table of contents

Time complexity and space complexity::

                                            1. Algorithm efficiency

                                            2. Time complexity

                                            3. Space complexity

                                            4. Common time complexity and complexity OJ exercises


Time complexity and space complexity::

What are data structures?

Data structure refers to the way computers store and organize data, and refers to a collection of data elements that have one or more specific relationships with each other.

What is an algorithm?

An algorithm is a well-defined computational process that takes a value or set of values ​​as input and produces a value or set of values ​​as output. Simply put, an algorithm
is a series of computational steps used to transform input data into output results.

For example: the data structure is to manage data in memory - add, delete, check and modify
           database is to manage data in disk - add, delete, check and change

           The B tree uses the binary search algorithm to use the search tree

1. Algorithm efficiency

  After the algorithm is written into an executable program, it needs to consume time resources and space (memory) resources when running. Therefore, the quality of an algorithm is generally
measured from two dimensions of time and space, namely time complexity and space complexity. .Time complexity mainly measures the running speed of an algorithm, while
  space complexity mainly measures the extra space required for an algorithm to run.
In the early days of computer development, the storage capacity of computers was very small, so they were very concerned about space complexity, but after With the rapid development of the computer industry
, the storage capacity of the computer has reached a very high level, so we no longer need to pay special attention to the space complexity of an algorithm. Moore's Law: The number of
  transistors that can be accommodated on an integrated circuit is approximately every 18 will double in a month.

2. Time complexity

The concept of time complexity:

Definition of time complexity: In computer science, the time complexity of an algorithm is a function that quantitatively describes the running time of the algorithm. The time it takes for an algorithm to execute cannot be calculated theoretically, only
you Only by running your program on the machine can we know.
But do we need to test each algorithm on the machine? Yes, we can test all the algorithms on the machine, but it is very troublesome, so there is an analysis method of time complexity.
One The time spent by the algorithm is directly proportional to the number of executions of the statement, and the number of executions of the basic operations in the algorithm is the time complexity of the algorithm. That is, to find the mathematical
expression between a statement and the problem size N is to calculate the The time complexity of the algorithm.

void Func1(int N)
{
	int count = 0;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++i)
		{
			++count;
		}
	}
	for (int k = 0; k < 2 * N; ++k)
	{
		++count;
	}
	int M = 10;
	while (M--)
	{
		++count;
	}
	printf("%d\n", count);
}
时间复杂度为:O(N^2)
void Func2(int N)
{
	int count = 0;
	for (int k = 0; k < 2 * N; ++k)
	{
		++count;
	}
	int M = 10;
	while (M--)
	{
		++count;
	}
	printf("%d\n", count);
}
时间复杂度为:O(N)
void Func3(int N, int M)
{
	int count = 0;
	for (int k = 0; k < M; ++k)
	{
		++count;
	}
	for (int k = 0; k < N; ++k)
	{
		++count;
	}
	printf("%d\n", count);
}
时间复杂度为:O(M+N)
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;
	}
}
时间复杂度为:O(N^2)
void Fun4(int N)
{
	int count = 0;
	for (int k = 0; k < 100; ++k)
	{
		++count;
	}
	printf("%d\n", count);
}
时间复杂度为:O(1)

Big O's asymptotic notation:
Big O notation is a mathematical notation used to describe the asymptotic behavior of a function.
To derive the big O asymptotic notation:
1. Replace all additive constants in run time with the constant 1.
2. After the modified number of runs In the function, only the highest-order item is kept.
3. If the highest-order coefficient exists and is not 1, remove the constant multiplied by this item, and the result is the big O order.

The time complexity of the algorithm has the best, worst and average cases:
worst case: the maximum number of runs (upper bound) for any input size
average case: the expected number of runs for any input size
best case: the minimum number of runs for any input size The number of times (lower bound)
For example: search for a data x in an array of length N
Best case: 1 time to find
Worst case: N times to find
Average case: N/2 times to find
In the actual situation, the most concerned is the algorithm Bad operation, so the time complexity of searching data in the array is O(N)

int BinarySearch(int* a, int n, int x)
{
	assert(a);
	int begin = 0;
	int end = n - 1;
	//[begin,end] begin和end是左闭右闭区间,因此有=号
	while (begin <= end)
	{
		int mid = begin + ((end - begin) >> 1);
		if (a[mid] < x)
			begin = mid + 1;
		else if (a[mid] > x)
			end = mid - 1;
		else
			return mid;
	}
	return -1; 
}
二分查找的最好情况是O(1)
二分查找的最坏情况是找不到 时间复杂度为O(logN)
每查找一次 查找区间个数减少一半(除2)
N/2/2/2.../2 = 1
longlong Fac(size_t N)
{
	if (1 == N)
		return 1;
	return Fac(N - 1) * N;
}
时间复杂度为O(N)
longlong Fib(size_t N)
{
	if (N < 3)
		return 1;
	return Fib(N - 1) + Fib(N - 2);
}
时间复杂度为O(2^N)
longlong Fib(size_t N)
{
	if (N < 3)
		return 1;
	longlong f1 = 1, f2 = 1, f3;
	for (size_t i = 3; i <= N; ++i)
	{
		f3 = f2 + f1;
		f1 = f2;
		f2 = f3;
	}
	return f3;
}
时间复杂度为O(N)

3. Space complexity

Space complexity is also a mathematical expression, which is a measure of the additional storage space occupied by an algorithm during operation.
Space complexity is not how many bytes of space the program occupies, because this is not very meaningful, so space complexity The calculation is the number of variables.
The space complexity calculation rules are basically similar to the time complexity, and the asymptotic representation of big O is also used.
Note: the stack space (storage parameters, local variables, some register information, etc.) required by the function when it is running ) has been determined during compilation, so the space complexity is mainly determined by the additional space requested by the function at runtime. 1G is about 1 billion bytes 1G
= 1024*1024*1024    
1M is about 1 million bytes 1M = 1024 *1024

计算BubbleSort的空间复杂度
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;
	}
}
空间复杂度为O(1)
计算Fac的空间复杂度
longlong Fac(size_t N)
{
	if (N == 0)
		return 1;
	return Fac(N - 1) * N;
}
空间复杂度为O(N)
每个函数栈帧是常数个 有N+1个Fac栈帧
计算Fib的空间复杂度
longlong Fib(size_t N)
{
	if (N < 3)
		return 1;
	return Fib(N - 1) + Fib(N - 2);
}
空间复杂度为O(N)

4. Common time complexity and complexity OJ exercises

The common complexity of the general algorithm is as follows:

        5201314              O(1)            constant order
          3n+4              O(n)            linear order
       3n^2+4n+5              O(n^2)            square order
       3log(2)n+4              O(logn)             logarithmic order
 2n+3nlog(2)n+14              O(n*logn)            nlogn order
 n^3+2n^2+4n+6              O(n^3)            cubic order
        2^n              O(2^n)            Exponential order

OJ exercises for complexity:

Disappearing numbers: 

int missingNumber(int* nums, int numSize)
{
	int x = 0;
	for (int i = 0; i < numSize; ++i)
	{
		x ^= nums[i];
	}
	for (int j = 0; i < numSize + 1; ++j)
	{
		x ^= j;
	}
	return x;
}
Rotate the array: 
void reverse(int* a, int begin, int end)
{
	while (begin < end)
	{
		int tmp = a[begin];
		a[begin] = a[end];
		a[end] = tmp;
		++begin;
		--end;
	}
}
void rotate(int* num, int numSize, int k)
{
	if (k > numSize)
		k %= numSize;
	reverse(nums, 0, numsSize - k - 1);
	reverse(nums, numSize - k, numsSize - 1);
	reverse(nums, 0, numsSize - 1);
}

Guess you like

Origin blog.csdn.net/qq_66767938/article/details/128926016