學習STL起因
大家都知道,數據結構是一門難懂的課,我在學習數據結構的時候發現,如果用純c語言寫代碼很難,看別人的題解大多都是c++ STL,爲了後面數據結構的學習效率上有所提高,特意過來了解一下STL。
模板
c++編程中,模板分爲函數模板和類模板。
1、函數模板
給一個例子:
/*
功能:比較兩個數的大小
*/
int Max(int a, int b)
{
if(a >= b)
{
return a;
}
return b;
}
傳參char a和char b,程序必然會報錯:參數類型不匹配。解決方法:
- 重載函數:char max(char a, char b)。在實際項目開發中,重載函數無疑會增加代碼量和工作量,影響開發效率。
- 模板:將上面max函數抽象成模板如下:
template <typename T>
T Max(T a, T b)
{
if(a >= b)
{
return a;
}
return b;
}
T:泛型類型。Max函數可以傳入任何類型的參數,而且不必重載,大大減少了代碼量,提高了代碼的可重用性。
2、類模板
給一個例子:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Compare
{
private:
T a;
T b;
public:
Compare(T x, T y)
{
a = x;
b = y;
}
T Max()
{
return a > b?a:b;
}
};
int main(int argc, char **argv)
{
try
{
/* code */
Compare<int> test1(2,3);//比較整型數據大小
Compare<char> test2('b','c');//比較字符型大小
cout<<test1.Max()<<endl;
cout<<test2.Max()<<endl;
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
return -1;
}
}
運行結果:
- 分析
代碼中我應用同一個類模板,分別進行了兩種不同類型數據的大小比較,並且正確輸出結果,對於不同的傳參,我們不需要重新定義新類,由此說明模板的使用可以提高項目的開發效率。
什麼是STL
-
Standard Template Library 簡稱STL,中文稱標準模板庫,把一些數據結構的算法抽象成模板類庫,是C++標準庫的一部分。
-
STL的組成:迭代器、算法、容器、仿函數、內存配置器和配接器。
容器
存儲和管理類模板,將所有類模板放在容器中,實例化後是容器類,我們通過調用這些類模板可以構建自己需要的數據結構,而不需要進行耗費體力的工作。
迭代器
迭代相當於for(i = 0; i < size; i++)中的i,在容器中迭代一般用begin()和end()表示,迭代器在每個容器中其着中介的作用,它瞭解容器的內部結構,提供一個接口用於訪問容器中的元素。
算法
處理元素的一種方法,比如排序、求最大最值、添加和刪除元素等,在迭代器的協助下,算法程序可以應用於各種容器。
仿函數
#include <iostream>
#include <string>
using namespace std;
/*第一種定義方式*/
template <typename T>
struct compare
{
T operator()(T a, T b)
{
return a > b?a:b;
}
};
/*第二種定義方式*/
template <typename T>
class compare1
{
public:
T operator()(T a, T b)
{
return a > b?a:b;
}
};
int main(int argc, char **argv)
{
compare<int> test1;
compare1<int> test2;
cout<<"使用對象調用:"<<test1(9,8)<<endl;
cout<<"使用仿函數調用:"<<compare<char>()('a','b')<<endl;
cout<<"使用test2對象調用:"<<test2(9,8)<<endl;
cout<<"使用仿函數調用:"<<compare1<char>()('a','b')<<endl;
return 0;
}
運行結果:
解析:
仿函數定義:關鍵詞是struct、opreator、class、public。
仿函數實質:類重載opreator(),仿函數執行效率比一般的函數指針高,使用仿函數調用operator時產生了一個臨時對象,僅佔1個字節,因爲沒有數據成員。
配接器
- 功能:可以實現不同類之間的數據轉換。最常用的配接器是istream_temtor,它提供了函數複製的接口。
- STL提供的配接器:
stack <Container>; queue <Container>; deque <Container>;
-
應用:力扣題
請實現一個函數按照之字形順序打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右到左的順序打印,第三行再按照從左到右的順序打印,其他行以此類推。解題思路:程序用到容器、配接器。
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;//定義一個返回二維數組
deque<struct TreeNode*> q;//定義一個雙端隊列
vector<int> EL_val;//定義暫存每層節點值的數組
struct TreeNode *node;//定義一個節點指針
if(!root)//參數合法性判斷
{
return res;
}
q.push_back(root);//將頭節點添加到隊列中
bool flag = true;//初始化一個從左到右打印節點的標誌
while(!q.empty())//隊列爲空說明樹已遍歷完
{
int EL_nums = q.size();//隊列中暫存每一層得所有節點,初始化每層的節點個數
cout<<"EL_nums="<<EL_nums<<endl;
while(EL_nums)//層節點打印完跳出循環
{
if(flag)//從從左到右打印節點,前取後進
{
node = q.front();//從前面取節點
q.pop_front();//刪除節點
if(node->left)
{
q.push_back(node->left);
}
if(node->right)
{
q.push_back(node->right);
}
}
else//從右向左打印節點,前進後取
{
node = q.back();//從後面取節點
q.pop_back();//刪除節點
if(node->right)
{
q.push_front(node->right);
}
if(node->left)
{
q.push_front(node->left);
}
}
EL_val.push_back(node->val);
EL_nums--;
}
flag = !flag;//正序逆序交替打印
res.push_back(EL_val);//將每層節點裝入二維數組中
EL_val.clear();//將每層節點清空,以便裝下一層節點
}
return res;
}
內存配置器
- 作用:主要用於爲容器對象管理內存空間的,包括分配對象空間和釋放對象空間。
參考學習適配器:https://www.cnblogs.com/tp-16b/p/9186826.html
參考學習STL知識框架:https://blog.csdn.net/qq_21950929/article/details/79808690