數據結構算法利器--STL

學習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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章