C語言數(shù)據(jù)結(jié)構(gòu)之算法的時間復雜度
1、算法的復雜度
算法在編寫成可執(zhí)行程序后,運行時需要耗費時間資源和空間(內(nèi)存)資源 。因此衡量一個算法的好壞,一般是從時間和空間兩個維度來衡量的,即時間復雜度和空間復雜度。
時間復雜度主要衡量一個算法的運行快慢,而空間復雜度主要衡量一個算法運行所需要的額外空間。在計算機發(fā)展的早期,計算機的存儲容量很小。所以對空間復雜度很是在乎。但是經(jīng)過計算機行業(yè)的迅速發(fā)展,計算機的存儲容量已經(jīng)達到了很高的程度。所以我們?nèi)缃褚呀?jīng)不需要再特別關注一個算法的空間復雜度。(本篇文章主要討論時間復雜度)
2、時間復雜度
2.1 時間復雜度的定義
時間復雜度的定義:在計算機科學中,算法的時間復雜度是一個函數(shù),它定量描述了該算法的運行時間。一個算法執(zhí)行所耗費的時間,從理論上說,是不能算出來的,只有你把你的程序放在機器上跑起來,才能知道。但是我們需要每個算法都上機測試嗎?是可以都上機測試,但是這很麻煩,所以才有了時間復雜度這個分析方式。一個算法所花費的時間與其中語句的執(zhí)行次數(shù)成正比例,算法中的基本操作的執(zhí)行次數(shù),為算法的時間復雜度。
舉例:
請計算一下Func1中++count語句總共執(zhí)行了多少次?
void Func1(int N)
{
int count = 0;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
++count;
}
}
for (int k = 0; k < 2 * N; ++k)
{
++count;
}
int M = 10;
while (M--)
{
++count;
}
printf("%d\n", count);
}時間復雜度函數(shù):F(N)=N*N+2*N+10

實際中我們計算時間復雜度時,我們其實并不一定要計算精確的執(zhí)行次數(shù),而只需要大概執(zhí)行次數(shù),那么這里我們使用大O的漸進表示法。
2.2 大O的漸進表示法
大O符號(Big O notation):是用于描述函數(shù)漸進行為的數(shù)學符號
1、用1來代替常數(shù),F(N)函數(shù)只有常數(shù) O(1)
2、在運行次數(shù)中,只保留最高階。 F(N)=N^3+N^2 --> O(N^3)
3、最高項系數(shù)化為1。F(N) = 2*N --> O(N)
注:復雜度不固定時,時間復雜度看的是最壞的情況(悲觀的估算)
例如:在一個長度為N數(shù)組中搜索一個數(shù)據(jù)x
- 最好情況:1次找到
- 最壞情況:N次找到
- 平均情況:N/2次找到
在實際中一般情況關注的是算法的最壞運行情況,所以數(shù)組中搜索數(shù)據(jù)時間復雜度為O(N)
3、常見時間復雜度計算舉例
3.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;
}
}
經(jīng)分析的:F(N)= O(N^2)
3.2 二分查找的時間復雜度
//左閉右開
int BinarySearch(int* a, int n, int x)
{
assert(a);
int begin = 0;
int end = n ;
while (begin < end)
{
int mid = begin + ((end - begin) >> 1);
if (a[mid] < x)
begin = mid + 1;
else if (a[mid] > x)
end = mid;
else
return mid;
}
return -1;
}
//左閉右閉
int BinarySearch(int* a, int n, int x)
{
assert(a);
int begin = 0;
int end = n-1;
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;
}假設找了x次:
1*2*2*2*2......*2 = N
2^x = N
x = log2 N
最壞:O(log2 N) 簡寫成 log(N)

3.3 階乘(遞歸)的時間復雜度
- 1、每次函數(shù)調(diào)用是O(1),那么就要看他的遞歸次數(shù)。
- 2、每次函數(shù)調(diào)用不是O(n),那么就看他的遞歸調(diào)用中次數(shù)的累加。
long long Fac(size_t N)
{
if (0 == N)
return 1;
return Fac(N - 1) * N;
}
F(N) = O(N)
3.4菲波那切數(shù)列的時間復雜度
long long Fib(size_t N)
{
if (N < 3)
return 1;
return Fib(N - 1) + Fib(N - 2);
}

通過計算分析發(fā)現(xiàn)基本操作遞歸了2^N次,時間復雜度為O(2^N)。
到此這篇關于C語言數(shù)據(jù)結(jié)構(gòu)之算法的時間復雜度的文章就介紹到這了,更多相關c語言算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
STL區(qū)間成員函數(shù)及區(qū)間算法總結(jié)
這篇文章主要匯總介紹了STL區(qū)間成員函數(shù)及區(qū)間算法,有需要的小伙伴可以參考下。2015-07-07

