C語言數(shù)據(jù)結(jié)構(gòu)的時間復(fù)雜度和空間復(fù)雜度
一、數(shù)據(jù)結(jié)構(gòu)前言
1.什么是數(shù)據(jù)結(jié)構(gòu):
數(shù)據(jù)結(jié)構(gòu)(Data Structure)是計算機(jī)存儲、組織數(shù)據(jù)的方式,指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合
2.什么是算法?
算法(Algorithm):就是定義良好的計算過程,他取一個或一組的值為輸入,并產(chǎn)生出一個或一組值作為輸出。簡單來說算法就是一系列的計算步驟,用來將輸入數(shù)據(jù)轉(zhuǎn)化成輸出結(jié)果
通俗來說:二分查找,冒泡排序等等都為算法
3.如何學(xué)好算法和數(shù)據(jù)結(jié)構(gòu)
1.多寫代碼(寫到吐)
2.勤于思考多畫圖
注:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)為軟件開發(fā)打下深厚功底,提升代碼能力
二、算法的時間復(fù)雜度和空間復(fù)雜度
1.算法效率
1.1如何衡量一個算法的好壞
比如對于以下斐波那契數(shù)列:
long long Fib(int N) { if (N < 3) return 1; return Fib(N - 1) + Fib(N - 2); }
1.2算法的復(fù)雜度
算法在編寫成可執(zhí)行程序后,運(yùn)行時需要耗費(fèi)時間資源和空間(內(nèi)存)資源 。因此衡量一個算法的好壞,一般是從時間和空間兩個維度來衡量的,即時間復(fù)雜度和空間復(fù)雜度。時間復(fù)雜度主要衡量一個算法的運(yùn)行快慢,而空間復(fù)雜度主要衡量一個算法運(yùn)行所需要的額外空間。在計算機(jī)發(fā)展的期,計算機(jī)的存儲容量很小。所以對空間復(fù)雜度很是在乎。但是經(jīng)過計算機(jī)行業(yè)的迅速發(fā)展,計算機(jī)的存儲容量已經(jīng)達(dá)到了很高的程度。所以我們?nèi)缃褚呀?jīng)不需要再特別關(guān)注一個算法的空間復(fù)雜度。
2.時間復(fù)雜度
2.1 時間復(fù)雜度的概念
時間復(fù)雜度的定義:在計算機(jī)科學(xué)中,算法的時間復(fù)雜度是一個函數(shù),它定量描述了該算法的運(yùn)行時間。一個算法執(zhí)行所耗費(fèi)的時間,從理論上說,是不能算出來的,只有你把你的程序放在機(jī)器上跑起來,才能知道。但是我們需要每個算法都上機(jī)測試嗎?是可以都上機(jī)測試,但是這很麻煩,所以才有了時間復(fù)雜度這個分析方式。一個算法所花費(fèi)的時間與其中語句的執(zhí)行次數(shù)成正比例
注:算法中的基本操作的執(zhí)行次數(shù),為算法的時間復(fù)雜度。
求其時間復(fù)雜度:
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ù)雜度時,我們其實并不一定要計算精確的執(zhí)行次數(shù),而只需要大概執(zhí)行次數(shù),那么這里我們使用大O的漸進(jìn)表示法
2.2大O的漸進(jìn)表示法
大O符號(Big O notation):是用于描述函數(shù)漸進(jìn)行為的數(shù)學(xué)符號。
推導(dǎo)大O階方法:
1、用常數(shù)1取代運(yùn)行時間中的所有加法常數(shù)。
2、在修改后的運(yùn)行次數(shù)函數(shù)中,只保留最高階項。
3、如果最高階項存在且不是1,則去除與這個項目相乘的常數(shù)。得到的結(jié)果就是大 O 階。
使用大O的漸進(jìn)表示法以后,F(xiàn)unc1的時間復(fù)雜度為: N^2
N = 10 F(N) = 100
N = 100 F(N) = 10000
N = 1000 F(N) = 1000000
實例1.計算Func2的時間復(fù)雜度?
// 計算Func2的時間復(fù)雜度? 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); }
實例2.計算Func3的時間復(fù)雜度?
// 計算Func3的時間復(fù)雜度? 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); }
實例3:計算Func4的時間復(fù)雜度?
// 計算Func4的時間復(fù)雜度? void Func4(int N) { int count = 0; for (int k = 0; k < 100; ++ k) { ++count; } printf("%d\n", count); }
時間復(fù)雜度并不代表1次,而是常數(shù)次
實例4:計算strchr的時間復(fù)雜度
//計算strchr的時間復(fù)雜度 const char * strchr ( const char * str, int character ); { while(*str) { if(*str == character) { return str; } } }
有些算法的時間復(fù)雜度存在最好、平均和最壞情況:
最壞情況:任意輸入規(guī)模的最大運(yùn)行次數(shù) ( 上界 )
平均情況:任意輸入規(guī)模的期望運(yùn)行次數(shù)
最好情況:任意輸入規(guī)模的最小運(yùn)行次數(shù) ( 下界 )
3.空間復(fù)雜度
空間復(fù)雜度也是一個數(shù)學(xué)表達(dá)式,是對一個算法在運(yùn)行過程中 臨時占用存儲空間大小的量度 。
空間復(fù)雜度不是程序占用了多少 bytes 的空間,因為這個也沒太大意義,所以空間復(fù)雜度算的是變量的個數(shù)。
空間復(fù)雜度計算規(guī)則基本跟實踐復(fù)雜度類似,也使用 大 O 漸進(jìn)表示法 。
注意:函數(shù)運(yùn)行時所需要的??臻g(存儲參數(shù)、局部變量、一些寄存器信息等)在編譯期間已經(jīng)確定好了,因此空間復(fù)雜度主要通過函數(shù)在運(yùn)行時候顯式申請的額外空間來確定。
4. 常見復(fù)雜度對比
一般算法常見的復(fù)雜度如下:
到此這篇關(guān)于C語言數(shù)據(jù)結(jié)構(gòu)的時間復(fù)雜度和空間復(fù)雜度的文章就介紹到這了,更多相關(guān)C語言時間與空間復(fù)雜度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++標(biāo)準(zhǔn)模板庫函數(shù)sort的那些事兒
sort函數(shù)是標(biāo)準(zhǔn)模板庫的函數(shù),已知開始和結(jié)束的地址即可進(jìn)行排序,可以用于比較任何容器(必須滿足隨機(jī)迭代器),任何元素,任何條件,執(zhí)行速度一般比qsort要快2013-09-09