STL 数据结构部分原创入门教程,要详细资料请百度

数据结构部分

数据结构,按理而言是要计科的孩纸学一年,物联网的孩纸学半年的。不过,咱们也不需要那么细致的学习,其实太多的知识是能用就行的,现在让我们用一节课来ko基础的数据结构。

       数据结构是是什么呢,简单的理解就是数据如何的存储结构。我们之前学习过链表,那么实际上大多数的数据结构都是由链表来加以改装来实现,

      首先是list 双向链表,这个熟悉吧!

一定要注意其实容器都是类似的,学好一个后面的就刷刷会了。

头文件是 #include <list>

定义是  list <int> l1;  构造一个int 类型的 l1的空链表

               list <int> l1(3);  有三个元素,值都为0

        list <int> l1(3,1),; 有三个元素,值都为1

         我们可以对比的来上手,和数组对比,其实是一样的

     Int a[100];这是在定义数组,同样是指定类型就可以了,

    

1:要找第一个元素怎么找呢:

       数组 直接 a【0】;

       List   l1.front() ; //注意括号一定要有,其实这是一个函数返回值是他的首元素  2:找最后一个元素,

数组     a【99】;

List  l1.back();

3:访问中间元素,这个有点难度,要用指针,

       首先我们要定义指针:

List<int>::iterator it ;这个形式记住就可以,容器<类型>::iterator it  it = l1.begin();  返回开始位置的指针 

it = l1.end();  返回结束位置的下一个位置的指针

如何添加和删除呢??

Cin>>a;

L1.push_front(a);添加一个a到链表头

L1.push_back(a);到尾

L1.Pop_front();   删除一个头,无参数

L1.Pop_back();    删除一个尾,无参数

       L1.clear()删除所有。

        L1.erase(it ,it+5);删除一个或者一个区域

L1.Remove(4)删除链表中所有的4

L1.Remove_if(某函数)  删除满足条件的数,

       L1.Size()返回元素个数

        L1.Empty()判断是否空,空为真为true,否则为假false。

        L1.Reverse()反转链表

        L1.Sort()  正排序

        L1.Sort(greater<int>)逆排序

拿个题目练下,求次大值。和次小值。求全部的和。求长度。要求30行内实现。

#include<iostream>

#include<list>

#include<numeric>

using namespace std;

int main()

{

    list<int>l1;

    list<int>::iterator it, it1;

    int a,i,j=5;

    while(j--)

    {

        cin>>a;

        l1.push_front(a);

    }

    i = accumulate(l1.begin(),l1.end(),0);

    l1.sort();

    l1.pop_back();

    l1.pop_front();

    it = l1.begin();

    it1 = --l1.end();

    cout<<*it<<" "<<*it1<<" "<<l1.size()<<” ”<<i<<endl;

}

    list<int>l1;

    int a,j=5;

    while(j--){

       cin>>a;

       l1.push_front(a);

    }

    l1.sort();

    cout<<*++l1.begin()<<" "<<*(--(--l1.end()))<<" "<<l1.size()<<endl;

cout<<accumulate(l1.begin(),l1.end(),0)<<endl;

总结一下。链表除了不能随机访问以外,都是优点。链表功能非常强大。因为在增填数据和删除数据的时候,不像数组那样要移动大量数据。现在我们能懂一种结构了,那么我们快速的讲讲剩下的几种结构。主要由链表来解决的问题一般是一些大规模的数据,因为数组无法存放就可以使用,不过,STL里有一个不定长数组,也可以替代功能,希望大家多多看看这个链表的介绍,因为其他的结构其实运用的函数是一样的。

      在我的博客里也有一个文章上面是list的测试代码,可以直接拷贝来测试各个功能模块

数据结构之栈和队列

栈这个比较常见,主要用于解决括号配对ps南阳题2。走迷宫,这类运用栈的记忆能力的题目,在实际运用中,电子设备的状态一般都是使用栈来保存的,经常电脑出故障的时候会说什么堆栈溢出,就是这类问题。

      队列也常见,比方说,我们去食堂吃饭。就一个个排队,先进先出的结构。

他的作业就是能公平的逐个操作一遍。Ps:1197: 鸡蛋队列

那么如何使用这样的结构呢。

 注意他们本身其实就是链表,不过对数字的操作受到限制。

队列

头文件

stack 

queue

定义

stack<int> s1;

Queue<int>q1;

判断是否空

S1.empty()

Q1.empty()

求元素个数

S1.size()

Q1.size();

删除首元素

S1.pop()

Q1.pop()

获得首元素值

S1.top();

Q1.front()

加入新元素

S1.push()

Q1.push()

返回尾元素值

Q1.back();

队列嘛用的略少,所以我们来主要解析一下,括号匹配的代码

int main()

{    

        char b[10005];

        stack<char> a;

        scanf("%s",b);

        int l=strlen(b), p=0;

        if(b[0]==')'||b[0]==']'||b[0]=='}')

            printf("No ");

        else

        {

            for(int i=0;i<l;i++)

            {

                if(b[i]=='('||b[i]=='['||b[i]=='{') a.push(b[i]);

                else if(!a.empty()&&(a.top()+1==b[i]||a.top()+2==b[i])) {

                cout<<" "<<a.top()+1<<" "<<a.top()+2<<endl;a.pop();}

                else p=1;//a.top+1 +2 这个因为()【】{}的asc码差别是1 2.

            }

            if(a.empty()&&p==0) printf("Yes ");

            else printf("No ");

        }

    }

    return 0;

}

Map和set 这两个比较少用到,所以我只是描述一下他的性质,有同学在未来要用刀的话可以去我的博客里查看,有专题说明。

       Map  就是映射,代表一种一一对应的关系,比方学号和个人。比较类似我们用结构体来实现功能一样。特点是又自动排序的过程。

      Set  就是集合,任何数据只存在一个,无重复,并且有序。在加入元素的过程中就开始排序了。所以在对时间和内存要求高的题目就可以使用他们。

vector 这个叫向量,也是不定长数组,用法和数组一样。

Vector<int> v;

V[100] = “0”;

主要是用于弥补数组无法确定是开多大的情况下。和list互补,主要优点是可以快速随机访问。

       string 字符串

之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。
   好了,进入正题………
首先,为了在我们的程序中使用string类型,我们必须包含头文件 。如下:
   #include <string>//注意这里不是string.h string.h是C字符串头文件

1.声明一个C++字符串
声明一个字符串变量很简单:
   string Str;
这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String类的构造函数和析构函数如下:
a)    string s; //生成一个空字符串s
b)    string s(str) //拷贝构造函数 生成str的复制品
c)    string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值
d)    string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
e)    string s(cstr) //将C字符串作为s的初值
f)    string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。
g)    string s(num,c) //生成一个字符串,包含num个c字符
h)    string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值
i)    s.~string() //销毁所有字符,释放内存
都很简单,我就不解释了。


2.字符串操作函数
   这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。
a) =,assign()   //赋以新值
b) swap()   //交换两个字符串的内容
c) +=,append(),push_back() //在尾部添加字符
d) insert() //插入字符
e) erase() //删除字符
f) clear() //删除全部字符
g) replace() //替换字符 EF BB BF 3C 3F 78 6D 6C
h) + //串联字符串
i) ==,!=,<,<=,>,>=,compare() //比较字符串
j) size(),length() //返回字符数量
k) max_size() //返回字符的可能最大个数
l) empty() //判断字符串是否为空
m) capacity() //返回重新分配之前的字符容量
n) reserve() //保留一定量内存以容纳一定数量的字符
o) [ ], at() //存取单一字符
p) >>,getline() //从stream读取某值
q) << //将谋值写入stream
r) copy() //将某值赋值为一个C_string
s) c_str() //将内容以C_string返回
t) data() //将内容以字符数组形式返回
u) substr() //返回某个子字符串
v)查找函数
w)begin() end() //提供类似STL的迭代器支持
x) rbegin() rend() //逆向迭代器
y) get_allocator() //返回配置器

原文地址:https://www.cnblogs.com/luyi14/p/4305023.html