数据结构百科全书

数据结构

整理不易,全文比较长,而且有很多的代码段,建议收藏。

目录

vector (动态数组) 的使用`

文件名

vector.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们引入需要的头文件vector,在代码头部写下

#include <vector>

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {

    return 0;
}

第二步

讲解

首先我们学习如何使用一维的vector

main函数里面通过vector<int> v来定义一个储存整数的空的vector。当然vector可以存任何类型的数据,比如vector<string> v等等。在本课中我们用 int 来举例。

vector<int> v;

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;

    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;

    return 0;
}

第三步

讲解

我们把 \(1\)\(10\) 的平方依次存到vector
在刚才的定义下面写下

for (int i = 1; i <= 10; ++i) {
    v.push_back(i * i);
}

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }

    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }

    return 0;
}

第四步

讲解

然后依次输出我们刚才压入vector的值。继续写下

for (int i = 0; i < v.size(); ++i) {
    cout << v[i] << " ";
}
cout << endl;

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;

    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;

    return 0;
}

第五步

讲解

到这里,里可以点击运行看看效果。

接下来我们学习二维的vector的使用。二维的vector就是一个vector里面在套一个vector。通过如下的代码定义一个空的二维的vector。在刚才的输出代码后面继续写下,特别注意:里面的vector<int>后面有一个空格,这个空格不能到少,因为在没有开启 c++11 的情况下,会被识别成一个>>

vector<vector<int> > v2d;

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }

    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;

    return 0;
}

第六步

讲解

接下来我们给第一维赋值,第一维是一个一维的vector,在定义后面写下:

for (int i = 0; i < 5; ++i) {
    v2d.push_back(vector<int>());
}

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }

    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }

    return 0;
}

第七步

讲解

我们让第 \(i\) 行第 \(j\) 列的元素的值为 \(i*j\)。继续写下下面的代码:

for (int i = 0; i < v2d.size(); ++i) {
    for (int j = 0; j < 5; ++j) {
        v2d[i].push_back(i * j);
    }
}

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }
    for (int i = 0; i < v2d.size(); ++i) {
        for (int j = 0; j < 5; ++j) {
            v2d[i].push_back(i * j);
        }
    }

    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }
    for (int i = 0; i < v2d.size(); ++i) {
        for (int j = 0; j < 5; ++j) {
            v2d[i].push_back(i * j);
        }
    }

    return 0;
}

第八步

讲解

然后我们输出一个 \(5\)\(5\) 列的矩阵。

for (int i = 0; i < v2d.size(); ++i) {
    for (int j = 0; j < v2d[i].size(); ++j) {
        cout << v2d[i][j] << " ";
    }
    cout << endl;
}

提示

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }
    for (int i = 0; i < v2d.size(); ++i) {
        for (int j = 0; j < 5; ++j) {
            v2d[i].push_back(i * j);
        }
    }
    for (int i = 0; i < v2d.size(); ++i) {
        for (int j = 0; j < v2d[i].size(); ++j) {
            cout << v2d[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    for (int i = 1; i <= 10; ++i) {
        v.push_back(i * i);
    }
    for (int i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
    vector<vector<int> > v2d;
    for (int i = 0; i < 5; ++i) {
        v2d.push_back(vector<int>());
    }
    for (int i = 0; i < v2d.size(); ++i) {
        for (int j = 0; j < 5; ++j) {
            v2d[i].push_back(i * j);
        }
    }
    for (int i = 0; i < v2d.size(); ++i) {
        for (int j = 0; j < v2d[i].size(); ++j) {
            cout << v2d[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果。

聪明的你一定学会了vector怎么用了。

set (配对) 的使用`

文件名

set.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们引入需要的头文件set,在代码头部写下

#include <set>

代码

#include <iostream>
#include <set>
using namespace std;
int main() {

    return 0;
}

第二步

讲解

首先我们学习如何创建一个set

main函数里面通过set<string> country来定义一个储存字符串的空的set。当然set可以存任何类型的数据,比如set<int> s等等。在本课中我们用 string 来举例。

set<string> country;

提示

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;

    return 0;
}

代码

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;

    return 0;
}

第三步

讲解

我们把China America France依次插入到set
在刚才的定义下面写下

country.insert("China");
country.insert("America");
country.insert("France");

提示

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");

    return 0;
}

代码

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");

    return 0;
}

第四步

讲解

然后依次输出我们刚才插入set的字符串。继续写下

set<string>::iterator it;
for (it = country.begin(); it != country.end(); ++it) {
    cout << * it  << " ";
}
cout << endl;

提示

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;

    return 0;
}

代码

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;

    return 0;
}

第五步

讲解

到这里,里可以点击运行看看效果。
可以发现我们刚才插入的字符串按照字典序排列好了。

接下来我们学习set的删除操作。

country.erase("American");
country.erase("England");

提示

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;
    country.erase("American");
    country.erase("England");

    return 0;
}

代码

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;
    country.erase("American");
    country.erase("England");

    return 0;
}

第六步

讲解

接下来我们统计setChina字符串的个数

if (country.count("China")) {
    cout << "China in country." << endl;
}

提示

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;
    country.erase("American");
    country.erase("England");
    if (country.count("China")) {
        cout << "China in country." << endl;
    }

    return 0;
}

代码

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;
    country.erase("American");
    country.erase("England");
    if (country.count("China")) {
        cout << "China in country." << endl;
    }

    return 0;
}

第七步

讲解

最后我们将使用完成的set清空。继续写下下面的代码:

country.clear();

提示

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;
    country.erase("American");
    country.erase("England");
    if (country.count("China")) {
        cout << "China in country." << endl;
    }
    country.clear();

    return 0;
}

代码

#include <iostream>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for (it = country.begin(); it != country.end(); ++it) {
        cout << * it  << " ";
    }
    cout << endl;
    country.erase("American");
    country.erase("England");
    if (country.count("China")) {
        cout << "China in country." << endl;
    }
    country.clear();

    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果。

聪明的你一定学会了set怎么用了。

map (字典) 的使用`

文件名

map.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们引入需要的头文件map,在代码头部写下

#include <map>
#include <string>

代码

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {

    return 0;
}

第二步

讲解

首先我们学习如何创建一个map

main函数里面通过map<string, int> dict来定义一个key:value映射关系的空的map。当然map可以存任何类型的数据,比如map<int, int> m等等。在本课中我们用string:int来举例。

map<string, int> dict;

提示

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;

    return 0;
}

代码

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;

    return 0;
}

第三步

讲解

我们把Tom Jone Mary依次插入到map并一一对应的赋值。
在刚才的定义下面写下

dict["Tom"] = 1;
dict["Jone"] = 2;
dict["Mary"] = 1;

提示

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;

    return 0;
}

代码

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;

    return 0;
}

第四步

讲解

接下来我们查看mapMary对应的value值,先判断一下map中是否有Mary。继续写下

if (dict.count("Mary")) {
    cout << "Mary is in class " << dict["Mary"];
}

提示

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"];
    }

    return 0;
}

代码

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"];
    }

    return 0;
}

第五步

讲解

到这里,里可以点击运行看看效果。

接下来我们学习map的遍历操作。

for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
    cout << it->first << " is in class " << it->second << endl;
}

提示

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"];
    }
    for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
        cout << it->first << " is in class " << it->second << endl;
    }

    return 0;
}

代码

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"];
    }
    for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
        cout << it->first << " is in class " << it->second << endl;
    }

    return 0;
}

第六步

讲解

到这里,里可以点击运行看看效果。
可以发现map里的key字符串按照字典序排列好了。

最后我们再清空map

dict.clear();

提示

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"];
    }
    for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
        cout << it->first << " is in class " << it->second << endl;
    }
    dict.clear();
    return 0;
}

代码

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    map<string, int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"];
    }
    for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
        cout << it->first << " is in class " << it->second << endl;
    }
    dict.clear();
    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果。

聪明的你一定学会了map怎么用了。

stack (栈) 的使用`

文件名

stack.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们引入需要的头文件stack,在代码头部写下

#include <stack>

代码

#include <iostream>
#include <stack>
using namespace std;
int main() {

    return 0;
}

第二步

讲解

首先我们学习如何使用stack

main函数上方通过stack<int> S来定义一个全局栈来储存整数的空的stack。当然stack可以存任何类型的数据,比如stack<string> S等等。在本课中我们用 int 来举例。

stack<int> S;

提示

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {

    return 0;
}

代码

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {

    return 0;
}

第三步

讲解

我们把1 10 7三个数依次存到stack
main函数里写下

S.push(1);
S.push(10);
S.push(7);

提示

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {
    S.push(1);
    S.push(10);
    S.push(7);

    return 0;
}

代码

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {
    S.push(1);
    S.push(10);
    S.push(7);

    return 0;
}

第四步

讲解

然后我们判断一下stack的是否为空。继续写下

while (!S.empty()) {

}

提示

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {
    S.push(1);
    S.push(10);
    S.push(7);
    while (!S.empty()) {

    }

    return 0;
}

代码

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {
    S.push(1);
    S.push(10);
    S.push(7);
    while (!S.empty()) {

    }

    return 0;
}

第五步

讲解

如果stack不为空,我们将stack里的数依次取出来,在while里继续写下

cout << S.top() << endl;
S.pop();

提示

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {
    S.push(1);
    S.push(10);
    S.push(7);
    while (!S.empty()) {
      cout << S.top() << endl;
      S.pop();
    }
    return 0;
}

代码

#include <iostream>
#include <stack>
using namespace std;
stack<int> S;
int main() {
    S.push(1);
    S.push(10);
    S.push(7);
    while (!S.empty()) {
      cout << S.top() << endl;
      S.pop();
    }
    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果,可以发现stack有先进后出的特性。

聪明的你一定学会了stack怎么用了。

queue (队列) 的使用`

文件名

queue.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们引入需要的头文件queue,在代码头部写下

#include <queue>

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {

    return 0;
}

第二步

讲解

首先我们学习如何使用queue

main函数里面通过queue<int> q来定义一个储存整数的空的queue。当然queue可以存任何类型的数据,比如queue<string> q等等。在本课中我们用 int 来举例。

queue<int> q;

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;

    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;

    return 0;
}

第三步

讲解

我们把1 2 3三个数依次存到queue
main函数里写下

q.push(1);
q.push(2);
q.push(3);

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);

    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);

    return 0;
}

第四步

讲解

然后我们判断一下queue的是否为空。继续写下

while (!q.empty()) {

}

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {

    }

    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {

    }

    return 0;
}

第五步

讲解

如果queue不为空,我们将queue里的数依次取出来,在while里继续写下

cout << q.front() << endl;
q.pop();

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {
        cout << q.front() << endl;
        q.pop();
    }
    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {
        cout << q.front() << endl;
        q.pop();
    }
    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果,可以发现queue有先进先出的特性。

聪明的你一定学会了queue怎么用了。

priority_queue (优先队列) 的使用`

文件名

priority_queue.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们引入需要的头文件queue,在代码头部写下

#include <queue>

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {

    return 0;
}

第二步

讲解

首先我们学习如何使用priority_queue

main函数里面通过priority_queue<int> q来定义一个储存整数的空的priority_queue。当然priority_queue可以存任何类型的数据,比如priority_queue<string> q等等。在本课中我们用 int 来举例。

priority_queue<int> q;

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;

    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;

    return 0;
}

第三步

讲解

我们把1 2 3三个数依次存到priority_queue
main函数里写下

q.push(1);
q.push(2);
q.push(3);

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);

    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);

    return 0;
}

第四步

讲解

然后我们判断一下priority_queue的是否为空。继续写下

while (!q.empty()) {

}

提示

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {

    }

    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {

    }

    return 0;
}

第五步

讲解

如果priority_queue不为空,我们将priority_queue里的数依次取出来,在while里继续写下

cout << q.top() << endl;
q.pop();

提示

#include <iostream>
#include <priority_queue>
using namespace std;
int main() {
    priority_queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {
        cout << q.top() << endl;
        q.pop();
    }
    return 0;
}

代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    priority_queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty()) {
        cout << q.top() << endl;
        q.pop();
    }
    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果,可以发现priority_queue会自动从大到小排好序。

聪明的你一定学会了priority_queue怎么用了。

disjoint (并查集) 的使用`

文件名

disjoint.cpp

分数

1


初始化代码

#include <iostream>
using namespace std;

int main() {

    return 0;
}

第一步

讲解

首先我们需要定义节点个数nfather父节点数组,dist距离数组,size权值数组,在main函数上方写下

int father[110], n;
int dist[110], size[110];

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];
int main() {

    return 0;
}

第二步

讲解

然后对这些数组进行初始化。在main函数里写下

n = 10;
init();

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];
int main() {
    n = 10;
    init();

    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];
int main() {
    n = 10;
    init();

    return 0;
}

第三步

讲解

接下来具体实现init函数。继续在main函数上面写下

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int main() {
    n = 10;
    init();

    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int main() {
    n = 10;
    init();

    return 0;
}

第四步

讲解

现在开始学习并查集的merge操作,我们将121073437合并。在main函数里继续写下

merge(1, 2);
merge(10, 7);
merge(3, 4);
merge(3, 7);

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);

    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);

    return 0;
}

第五步

讲解

接下来我们具体实现merge函数。在main上方继续写下

void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);

    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);

    return 0;
}

第六步

讲解

接下来我们查找1所在集合的根节点并输出1到根节点的距离dist。在main函数里继续写下

get(1); // 一定要先 get,可能没有直接连接根节点
cout << dist[1] + 1 << endl;

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);
    get(1); // 一定要先 get,可能没有直接连接根节点
    cout << dist[1] + 1 << endl;

    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);
    get(1); // 一定要先 get,可能没有直接连接根节点
    cout << dist[1] + 1 << endl;

    return 0;
}

第七步

讲解

我们接着实现get函数。在merge函数上方继续写下

int get(int x) {
    if (father[x] == x) {
        return x;
    }
    int y = father[x];
    father[x] = get(y);
    dist[x] += dist[y];
    return father[x];
}

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int get(int x) {
    if (father[x] == x) {
        return x;
    }
    int y = father[x];
    father[x] = get(y);
    dist[x] += dist[y];
    return father[x];
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);
    get(1); // 一定要先 get,可能没有直接连接根节点
    cout << dist[1] + 1 << endl;

    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int get(int x) {
    if (father[x] == x) {
        return x;
    }
    int y = father[x];
    father[x] = get(y);
    dist[x] += dist[y];
    return father[x];
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);
    get(1); // 一定要先 get,可能没有直接连接根节点
    cout << dist[1] + 1 << endl;

    return 0;
}

第八步

讲解

到这里,里可以点击运行看看效果。

接下来我们查找3所在集合的根节点并输出3到根节点的距离dist。在main函数里继续写下

get(3);
cout << dist[3] + 1 << endl;

提示

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int get(int x) {
    if (father[x] == x) {
        return x;
    }
    int y = father[x];
    father[x] = get(y);
    dist[x] += dist[y];
    return father[x];
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);
    get(1); // 一定要先 get,可能没有直接连接根节点
    cout << dist[1] + 1 << endl;
    get(3);
    cout << dist[3] + 1 << endl;
    return 0;
}

代码

#include <iostream>
using namespace std;
int father[110], n;
int dist[110], size[110];

void init() {
    for (int i = 1; i <= n; ++i) {
        father[i] = i, dist[i] = 0, size[i] = 1;
    }
}
int get(int x) {
    if (father[x] == x) {
        return x;
    }
    int y = father[x];
    father[x] = get(y);
    dist[x] += dist[y];
    return father[x];
}
void merge(int a, int b) {
    a = get(a);
    b = get(b);
    if (a != b) {
        father[a] = b;
        dist[a] = size[b];
        size[b] += size[a];
    }
}
int main() {
    n = 10;
    init();
    merge(1, 2);
    merge(10, 7);
    merge(3, 4);
    merge(3, 7);
    get(1); // 一定要先 get,可能没有直接连接根节点
    cout << dist[1] + 1 << endl;
    get(3);
    cout << dist[3] + 1 << endl;
    return 0;
}

完成讲解

这一节已经完成了,赶紧运行看看效果。

聪明的你一定学会了disjoint怎么用了。

队列`

简介

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

  • 重要特性:元素先进先出

实现方式

  • 数组
  • 链表
  • STL

标程

#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

struct Queue {
    /* 数组实现 */
    void Queue_Array() {
        int q[1005] = {0};
        int head = 0;
        int tail = head;
        q[tail++] = 1;
        q[tail++] = 2;
        q[tail++] = 3;
        while (head < tail) {
            printf("%d\n", q[head]);
            head++;
        }
    }

    /* STL实现 */
    void Queue_STL() {
        queue<int> q;
        q.push(1);
        q.push(2);
        q.push(3);
        while (!q.empty()) {
            printf("%d\n", q.front());
            q.pop();
        }
    }
}Q;

int main() {
    Q.Queue_Array();
    Q.Queue_STL();
    return 0;
}

单调队`

简介

单调队列,即单调递减或单调递增的队列。使用频率不高,但在有些程序中会有非同寻常的作用。

  • 重要特性:元素可以从两端进出

实现方式

  • 数组
  • 链表
  • STL

deque的性质

  • 容器中间插入和删除效率很低
  • 与vector容器操作类似

例题

题意:n个数字一开始排成一行,有两个指针L和R,指向了这串数字的一个区间的端点。
现在有7种操作

  • 使一个指针左移
  • 使一个指针右移
  • 在L后插入一个数字X
  • 在R前插入一个数字X
  • 删除L所指元素
  • 删除R所指元素
  • 翻转[L,R]区间

Question:m次操作后,整串数字是什么样的?

分析:如果区间L和R每一次都是任意范围的,那么肯定是平衡树问题。但是现在区间断点L和R每次只能左移一位或右移一位,那么可以将整串数字以L、R为中点分为三段,然后模拟这几种操作。但是翻转不能直接模拟,用一个标记来判断一下正反。

双端队列`

简介

双端队列(deque,全名double-ended queue)是一个限定插入和删除操作的数据结构,具有队列和栈的性质。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。
双端队列是限定插入和删除操作在表的两端进行的线性表。这两端分别称做端点1和端点2。也可像栈一样,可以用一个铁道转轨网络来比喻双端队列。

  • 重要特性:元素可以从两端进出

实现方式

  • 数组
  • 链表
  • STL

deque的性质

  • 容器中间插入和删除效率很低
  • 与vector容器操作类似

例题

题意:n个数字一开始排成一行,有两个指针L和R,指向了这串数字的一个区间的端点。
现在有7种操作

  • 使一个指针左移
  • 使一个指针右移
  • 在L后插入一个数字X
  • 在R前插入一个数字X
  • 删除L所指元素
  • 删除R所指元素
  • 翻转[L,R]区间

Question:m次操作后,整串数字是什么样的?

分析:如果区间L和R每一次都是任意范围的,那么肯定是平衡树问题。但是现在区间断点L和R每次只能左移一位或右移一位,那么可以将整串数字以L、R为中点分为三段,然后模拟这几种操作。但是翻转不能直接模拟,用一个标记来判断一下正反。

标程

#include<algorithm>
#include<deque>
#include<iostream>
using namespace std;

int main() {
    deque<int> dq;
    dq.push_back(1);
    dq.push_back(2);
    dq.push_back(3);
    dq.push_front(4);
    dq.push_front(5);
    dq.push_front(6);
    dq.pop_back();
    dq.pop_front();
    deque<int>::iterator it;
    for (it = dq.begin(); it != dq.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}

posted @ 2020-07-22 13:59  SweepyZhou  阅读(351)  评论(0)    收藏  举报