队列queue + 栈stack + 优先队列priority_queue + 双端队列deque+ 双向链表list

目录

队列和栈对比

队列queue

基本知识

一、基于数组的循环队列(循环队列)

例1:简单队列操作

例2:循环队列的C++实现

栈stack

基本知识

1. 基于数组的栈

2. 基于单链表的栈

两个栈stack实现一个队列queue

两个队列queue实现一个栈stack

优先队列 priority_queue

基本内容

头文件 #include 

和队列基本操作相同:

定义

大顶堆与小顶堆

pair类型,先比较第一个元素,第一个相等比较第二个

自定义优先级

双端队列deque

操作图示:

deque的特点:

最好采用deque的情形:

deque的操作函数  博客园-deque

定义函数

容量函数

 添加函数

 删除函数

访问函数

其他函数

 迭代器与算法

1. 迭代器

2. 算法

遍历元素

元素翻转 

元素排序

双向链表List

基本知识

基本操作

容量函数

添加函数

删除元素

其他函数

迭代器与算法

迭代器

算法

遍历

元素翻转

元素排列

总结


队列和栈对比

队列:

q.empty()               如果队列为空返回true,否则返回false
q.size()                返回队列中元素的个数
q.pop()                 删除队列首元素但不返回其值
q.front()               返回队首元素的值,但不删除该元素
q.push()                在队尾压入新元素
q.back()                返回队列尾元素的值,但不删除该元素

栈:

s.empty();         //如果栈为空则返回true, 否则返回false;
s.size();          //返回栈中元素的个数
s.top();           //返回栈顶元素, 但不删除该元素
s.pop();           //弹出栈顶元素, 但不返回其值
s.push();          //将元素压入栈顶

队列queue

基本知识

1、 先进先出

2、在队尾添加元素,在队头删除元素。

3、C++队列queue模板类的定义在<queue>头文件中,queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque 类型。C++队列Queue是一种容器适配器,它给予程序员一种先进先出(FIFO)的数据结构。

 那么我们如何判断队列是空队列还是已满呢?

      a、栈空: 队首标志=队尾标志时,表示栈空。

      b、栈满 : 队尾+1 = 队首时,表示栈满。

使用标准库的队列时, 应包含相关头文件,在栈中应包含头文件: #include< queue> 。

定义:queue< int > q;

q.empty()               如果队列为空返回true,否则返回false
q.size()                返回队列中元素的个数
q.pop()                 删除队列首元素但不返回其值
q.front()               返回队首元素的值,但不删除该元素
q.push()                在队尾压入新元素
q.back()                返回队列尾元素的值,但不删除该元素

一、基于数组的循环队列(循环队列)

以数组作为底层数据结构时,一般讲队列实现为循环队列。这是因为队列在顺序存储上的不足:每次从数组头部删除元素(出队)后,需要将头部以后的所有元素往前移动一个位置,这是一个时间复杂度为O(n)的操作。

循环队列的抽象数据类型:

template <typename T>
class LoopQueue
{
public:
    LoopQueue(int c = 10);
    ~LoopQueue();  //析构函数
public:
    bool isEmpty();        //队列的判空
    int size();            //队列的大小
    bool push(T t);        //入队列
    bool pop();            //出队列
    T front();            //队首元素
 
private:
    int capacity;
    int begin;
    int end;
    T*  queue;
};

定义front为队列头元素的位置,rear为队列尾元素的位置,MAXSIZE为循环队列的最大长度。注意以下几点,循环队列迎刃而解:

  •   求元素的个数:(rear - front + MAXSIZE) % MAXSIZE
  •   front/rear指向逻辑的下一个空间  front =(front+1)%MAXSIZE,rear = (rear+1)%MAXSIZE
  •   判空:front == rear
  •   判满:(rear+1+MAXSZIE) == front
     

例1:简单队列操作

#include <queue>
#include <iostream>
using namespace std;
 
int main(){
	queue<int> q;
	for (int i = 0; i < 10; i++){
		q.push(i);
	}
	if (!q.empty()){
		cout << "队列q非空!" << endl;
		cout << "q中有" << q.size() << "个元素" << endl;
	}
	cout << "队头元素为:" << q.front() << endl;
	cout << "队尾元素为:" << q.back() << endl;
	for (int j = 0; j < 10; j++){
		int tmp = q.front();
		cout << tmp << " ";
		q.pop();
	}
	cout << endl;
	if (!q.empty()){
		cout << "队列非空!" << endl;
	}
	system("pause");
	return 0;
}

例2:循环队列的C++实现

C++数据结构——队列_GeekZW的博客-CSDN博客_c++队列

#include <iostream>
#include <queue>
#include <string>
using namespace std;
 
template <typename T>
class LoopQueue
{
public:
	LoopQueue(int c = 10);
	~LoopQueue();
	bool isEmpty();        //队列的判空
	int size();            //队列的大小
	bool push(T t);        //入队列
	bool pop();            //出队列
	T front();            //队首元素
 
private:
	int capacity;
	int begin;
	int end;
	T*  queue;
};
 
 
template<typename T>
LoopQueue<T>::LoopQueue(int c = 10)
	:capacity(c), begin(0), end(0), queue(nullptr)
{
	queue = new T[capacity];
};
 
template<typename T>
LoopQueue<T>::~LoopQueue()
{
	delete[]queue;
}
 
template <typename T>
bool LoopQueue<T>::isEmpty()                   //判断循环队列是否为空
{
	if (begin == end)
		return true;
	return false;
};
 
template<typename T>
int LoopQueue<T>::size()
{
	return (end - begin + capacity) % capacity; //计算循环队列的长度
};
 
template<typename T>
bool LoopQueue<T>::push(T t)
{
	if (end + 1 % capacity == begin)            //判断队列是否已满
	{
		return false;
	}
	queue[end] = t;
	end = (end + 1) % capacity;
	return true;
};
 
template <typename T>
bool LoopQueue<T>::pop()                        //判断队列是否为空
{
	if (end == begin) 
	{
		return false;
	}
	begin = (begin + 1) % capacity;
	return true;
};
 
template <typename T>
T LoopQueue<T>::front()
{
	if (end == begin)
	{
		return false;
	}
	return queue[begin];
};
 
int main()
{
	LoopQueue<string> queue(6);
	queue.push("one");
	queue.push("two");
	queue.push("three");
	queue.push("four");
	queue.push("five");
	cout << "队列长度" << queue.size() << endl;
	while (!queue.isEmpty())
	{
		cout << queue.front() << endl;
		queue.pop();
	}
	getchar();
	//system("pause");
	return 0;
}


栈stack

基本知识

C++数据结构——栈_GeekZW的博客-CSDN博客_c++栈

1、先进后出
2、允许元素插入与删除的一端称为栈顶,另一端称为栈底
pop push
3、 在使用标准库的栈时,应该使用头文件: #include< stack >   ,若定义 stack <int> s;

s.empty();         //如果栈为空则返回true, 否则返回false;
s.size();          //返回栈中元素的个数
s.top();           //返回栈顶元素, 但不删除该元素
s.pop();           //弹出栈顶元素, 但不返回其值
s.push();          //将元素压入栈顶


1. 基于数组的栈

以数组为底层数据结构时,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向。

#include <stack>
#include <iostream>
using namespace std;
 
int main()
{
    stack<int> mystack;
    int sum = 0;
    for (int i = 0; i <= 10; i++){
        mystack.push(i);
    }
    cout << "size is " << mystack.size() << endl;
    while (!mystack.empty()){
        cout << " " << mystack.top();
        mystack.pop();
    }
    cout << endl;
    system("pause");
    return 0;
}
//size is 11
// 10 9 8 7 6 5 4 3 2 1 0

2. 基于单链表的栈

以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部。

#include <iostream>
using namespace std;
template<class T>class Stack
{
private:
    struct Node
    {
        T data;
        Node *next;
    };
    Node *head;
    Node *p;
    int length;
 
public:
    Stack()
    {
        head = NULL;
        length = 0;
    }
    void push(T n)//入栈
    {
        Node *q = new Node;
        q->data = n;
        if (head == NULL)
        {
            q->next = head;
            head = q;
            p = q;
        }
        else
        {
            q->next = p;
            p = q;
        }
        length++;
    }
 
    T pop()//出栈并且将出栈的元素返回
    {
        if (length <= 0)
        {
            abort();
        }
        Node *q;
        T data;
        q = p;
        data = p->data;
        p = p->next;
        delete(q);
        length--;
        return data;
    }
    int size()//返回元素个数
    {
        return length;
    }
    T top()//返回栈顶元素
    {
        return p->data;
    }
    bool isEmpty()//判断栈是不是空的
    {
        if (length == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    void clear()//清空栈中的所有元素
    {
        while (length > 0)
        {
            pop();
        }
    }
};
int main()
{
    Stack<char> s;
    s.push('a');
    s.push('b');
    s.push('c');
    while (!s.isEmpty())
    {
        cout << s.pop() << endl;
    }
    system("pause");
    return 0;
}

两个栈stack实现一个队列queue

队列的特性是 FIFOFIFO(先入先出),而栈的特性是 FILOFILO(先入后出)。

知道两者特性之后,我们需要用两个栈来模拟队列的特性,一个栈为入队栈,一个栈为出对栈

当出队栈存在内容时,出队栈的栈顶,即为第一个出队的元素。

若出队栈无元素,我们的需求又是出队的话,我们就需要将入队栈的内容反序导入出队栈,然后弹出栈顶即可。

注意:根据栈的的特性,我们仅能使用 pushpush 和 poppop 操作。

leetcode-232-解答

  • 可以把一个栈当做「输入栈」,把另一个栈当做「输出栈」。
  • 当 push() 新元素的时候,放到「输入栈」的栈顶,记此顺序为「输入序」。
  • 当 pop() 元素的时候,是从「输出栈」弹出元素。如果「输出栈」为空,则把「输入栈」的元素逐个 pop() 并且 push() 到「输出栈」中,这一步会把「输入栈」的栈底元素放到了「输出栈」的栈顶。此时负负得正,从「输出栈」的 pop() 元素的顺序与「输入序」相同。
class MyQueue {
private:
    stack<int> inStack, outStack;

    void in2out() {
        while (!inStack.empty()) {
            outStack.push(inStack.top());
            inStack.pop();
        }
    }

public:
    MyQueue() {}

    void push(int x) {
        inStack.push(x);
    }

    int pop() {
        if (outStack.empty()) {
            in2out();
        }
        int x = outStack.top();
        outStack.pop();
        return x;
    }

    int peek() {
        if (outStack.empty()) {
            in2out();
        }
        return outStack.top();
    }

    bool empty() {
        return inStack.empty() && outStack.empty();
    }
};

作者:demigodliu
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/tu-jie-guan-fang-tui-jian-ti-jie-yong-zh-4hru/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

两个队列queue实现一个栈stack

一个队列为主队列,一个为辅助队列,当入栈操作时,我们先将主队列内容导入辅助队列,然后将入栈元素放入主队列队头位置,再将辅助队列内容,依次添加进主队列即可。

class MyStack {
public:
    queue<int> queue1;
    queue<int> queue2;

    MyStack() {

    }

    void push(int x) {
        queue2.push(x);
        while (!queue1.empty()) {
            queue2.push(queue1.front());
            queue1.pop();
        }
        swap(queue1, queue2);
    }
    
    int pop() {
        int r = queue1.front();
        queue1.pop();
        return r;
    }
    
    int top() {
        int r = queue1.front();
        return r;
    }
    
    bool empty() {
        return queue1.empty();
    }
};

作者:demigodliu
链接:https://leetcode-cn.com/problems/implement-stack-using-queues/solution/wu-tu-guan-fang-tui-jian-ti-jie-yong-dui-63d4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

优先队列 priority_queue

基本内容

  • 头文件 #include <queue>

  • 和队列基本操作相同:

    • top 访问队头元素
    • empty 队列是否为空
    • size 返回队列内元素个数
    • push 插入元素到队尾 (并排序)
    • emplace 原地构造一个元素并插入队列
    • pop 弹出队头元素
    • swap 交换内容
  • 定义

priority_queue< type, container, function >

 后两个参数不可省略

  •     type:数据类型;
    •     container:实现优先队列的底层容器;  //必须是用数组实现的容器,比如vector,deque等等,但不能用 list。
      •     function:元素之间的比较方式

在STL中,默认情况下(不加后面两个参数)是以vector为容器,以 operator< 为比较方式,所以在只使用第一个参数时,优先队列默认是一个最大堆,每次输出的堆顶元素是此时堆中的最大元素。

  • 可以以O(log n) 的效率查找一个队列中的最大值或者最小值,其中是最大值还是最小值是根据创建的优先队列的性质来决定的。
  • 大顶堆与小顶堆

    1. 大顶堆

//构造一个空的优先队列(此优先队列默认为大顶堆)
priority_queue<int> big_heap;   

//另一种构建大顶堆的方法
priority_queue<int,vector<int>,less<int> > big_heap2;   

#include<iostream>
#include<queue>
using namespace std;

int main(){
	priority_queue<int> p;
	p.push(13356);
	p.push(23);
	p.push(85);
	p.push(536);
	p.push(43);
	for(int i=0;i<5;i++){
		cout<<p.top()<<endl;
		p.pop();
	}
	return 0;
}

    2. 小顶堆

//构造一个空的优先队列,此优先队列是一个小顶堆
priority_queue<int,vector<int>,greater<int> > small_heap;   
#include<iostream>
#include<queue>
using namespace std;

int main(){
	priority_queue<int, vector<int>, greater<int> >p;
	p.push(13356);
	p.push(23);
	p.push(85);
	p.push(536);
	p.push(43);
	for(int i=0;i<5;i++){
		cout<<p.top()<<endl;
		p.pop();
	}
	return 0;
}

  • pair类型,先比较第一个元素,第一个相等比较第二个

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{
    priority_queue<pair<int, int> > a;
    pair<int, int> b(68, 2);
    pair<int, int> c(167, 3);
    pair<int, int> d(268, 5);
    a.push(d);
    a.push(c);
    a.push(b);
    while (!a.empty())
    {
        cout << a.top().first << ' ' << a.top().second << '\n';
        a.pop();
    }
}

  • 自定义优先级

#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
struct Node{
	int x,y;
	Node(int a, int b):
		x(a), y(b) {}
};

struct cmp{
	bool operator()(Node a, Node b){
		if(a.x == b.x)	return a.y>b.y;
		return a.x>b.x;
	}
};

int main(){
	priority_queue<Node, vector<Node>, cmp>p;

	for(int i=0; i<10; ++i)
		p.push(Node(rand(), rand()));

	while(!p.empty()){
		cout<<p.top().x<<' '<<p.top().y<<endl;
		p.pop();
	}//while
	//getchar();
	return 0;
}

双端队列deque

操作图示:

deque的特点:

1、支持随机访问,即支持[]以及at(),但是性能没有vector好。

2、可以在内部进行插入和删除操作,但性能不及list。

最好采用deque的情形:

1、需要在两端插入和删除元素。

2、无需引用容器内的元素。

3、要求容器释放不再使用的元素。

deque的操作函数  博客园-deque

  • 定义函数

deque<int> a; // 定义一个int类型的双端队列a
deque<int> a(10); // 定义一个int类型的双端队列a,并设置初始大小为10
deque<int> a(10, 1); // 定义一个int类型的双端队列a,并设置初始大小为10且初始值都为1
deque<int> b(a); // 定义并用双端队列a初始化双端队列b
deque<int> b(a.begin(), a.begin()+3); // 将双端队列a中从第0个到第2个(共3个)作为双端队列b的初始值

除此之外,还可以直接使用数组来初始化向量:

int n[] = { 1, 2, 3, 4, 5 };
// 将数组n的前5个元素作为双端队列a的初值
// 说明:当然不包括arr[4]元素,末尾指针都是指结束元素的下一个元素,
// 这个主要是为了和deque.end()指针统一。
deque<int> a(n, n + 5); 
deque<int> a(&n[1], &n[4]); // 将n[1]、n[2]、n[3]作为双端队列a的初值
  • 容量函数

deq.size();   容器大小
deq.max_size();   容器最大容量
deq.resize();    更改容器大小:
deq.empty();    容器判空:
deq.shrink_to_fit();    减少容器大小到满足元素所占存储空间的大小:
  •  添加函数

deq.push_front(const T& x);  //头部添加元素
deq.push_back(const T& x);  //末尾添加元素
deq.insert(iterator it, const T& x);  //任意位置插入一个元素
deq.insert(iterator it, int n, const T& x);  任意位置插入 n 个相同元素
deq.insert(iterator it, iterator first, iterator last);  //插入另一个向量的 [forst,last] 间的数据
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
	deque<int> deq;

	// 头部增加元素
	deq.push_front(4);
	
	// 末尾添加元素
	deq.push_back(5);
	
	// 任意位置插入一个元素
	deque<int>::iterator it = deq.begin();
	deq.insert(it, 2);
	
	// 任意位置插入n个相同元素
	it = deq.begin(); // 必须要有这句
	deq.insert(it, 3, 9);
	
	// 插入另一个向量的[forst,last]间的数据
	deque<int> deq2(5,8);
	it = deq.begin(); // 必须要有这句
	deq.insert(it, deq2.end() - 1, deq2.end());

	// 遍历显示
	for (it = deq.begin(); it != deq.end(); it++)
		cout << *it << " "; // 输出:8 9 9 9 2 4 5
	cout << endl;

	return 0;
}
  •  删除函数

deq.pop_front();    头部删除元素:
deq.pop_back();   末尾删除元素: 
deq.erase(iterator it);    任意位置删除一个元素:
deq.erase(iterator first, iterator last);        删除 [first,last] 之间的元素:
deq.clear();       清空所有元素:
  • 访问函数

下标访问:deq[1];   并不会检查是否越界
at 方法访问:deq.at(1);   以上两者的区别就是 at 会检查是否越界,是则抛出 out of range 异常
访问第一个元素:deq.front();
访问最后一个元素:deq.back();
  • 其他函数

多个元素赋值:deq.assign(int nSize, const T& x);     类似于初始化时用数组进行赋值
交换两个同类型容器的元素:swap(deque&);
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
	// 多个元素赋值
	deque<int> deq;
	deq.assign(3, 1);
	deque<int> deq2;
	deq2.assign(3, 2);

	// 交换两个容器的元素
	deq.swap(deq2);

	// 遍历显示
	cout << "deq: ";
	for (int i = 0; i < deq.size(); i++)
		cout << deq[i] << " "; // 输出:2 2 2
	cout << endl;

	// 遍历显示
	cout << "deq2: ";
	for (int i = 0; i < deq2.size(); i++)
		cout << deq2[i] << " "; // 输出:1 1 1
	cout << endl;

	return 0;
}

 迭代器与算法

1. 迭代器

  • 开始迭代器指针:deq.begin();
  • 末尾迭代器指针:deq.end(); // 指向最后一个元素的下一个位置
  • 指向常量的开始迭代器指针:deq.cbegin(); // 意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
  • 指向常量的末尾迭代器指针:deq.cend();
  • 反向迭代器指针,指向最后一个元素:deq.rbegin();
  • 反向迭代器指针,指向第一个元素的前一个元素:deq.rend();

2. 算法

  • 遍历元素

deque<int>::iterator it;
for (it = deq.begin(); it != deq.end(); it++)
    cout << *it << endl;
// 或者
for (int i = 0; i < deq.size(); i++) {
    cout << deq.at(i) << endl;
}
  • 元素翻转 

#include <algorithm>
reverse(deq.begin(), deq.end());
  • 元素排序

#include <algorithm>
sort(deq.begin(), deq.end()); // 采用的是从小到大的排序

// 如果想从大到小排序,可以采用先排序后反转的方式,也可以采用下面方法:
// 自定义从大到小的比较器,用来改变排序方式
bool Comp(const int& a, const int& b) {
    return a > b;
}

sort(deq.begin(), deq.end(), Comp);

可以看到,deque 与 vector 的用法基本一致,除了以下几处不同:

  • deque 没有 capacity() 函数,而 vector 有;
  • deque 有 push_front() 和 pop_front() 函数,而 vector 没有;
  • deque 没有 data() 函数,而 vector 有。

其他均与vector相同。

注意:
1、除了at()函数,其他成员函数都不会检查索引或迭代器是否有效。2、元素的插入和删除可能会导致内存重新分配。所以任何插入或删除操作都会使所有指向deque元素的pointers、reference、iterators失效。唯一例外的是在首尾插入元素之后,pointers和reference可能仍然有效。


 

双向链表List

基本知识

  • #include <list>
  • 定义代码:
list<int> a; // 定义一个int类型的列表a
list<int> a(10); // 定义一个int类型的列表a,并设置初始大小为10
list<int> a(10, 1); // 定义一个int类型的列表a,并设置初始大小为10且初始值都为1
list<int> b(a); // 定义并用列表a初始化列表b
deque<int> b(a.begin(), ++a.end()); // 将列表a中的第1个元素作为列表b的初始值
int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5); // 将数组n的前5个元素作为列表a的初值

基本操作

容量函数

  • 容器大小:lst.size();
  • 容器最大容量:lst.max_size();
  • 更改容器大小为n:lst.resize(n);
  • 容器判空:lst.empty();

添加函数

  • 头部添加元素:lst.push_front(const T& x);
  • 末尾添加元素:lst.push_back(const T& x);
  • 任意位置插入一个元素:lst.insert(iterator it, const T& x);
  • 任意位置插入 n 个相同元素:lst.insert(iterator it, int n, const T& x);
  • 插入另一个向量的 [forst,last] 间的数据:lst.insert(iterator it, iterator first, iterator last);
#include <iostream>
#include <list>

using namespace std;

int main(int argc, char* argv[])
{
	list<int> lst;

	// 头部增加元素
	lst.push_front(4);
	// 末尾添加元素
	lst.push_back(5);
	// 任意位置插入一个元素
	list<int>::iterator it = lst.begin();
	lst.insert(it, 2);
	// 任意位置插入n个相同元素
	lst.insert(lst.begin(), 3, 9);
	// 插入另一个向量的[forst,last]间的数据
	list<int> lst2(5, 8);
	lst.insert(lst.begin(), lst2.begin(), ++lst2.begin());

	// 遍历显示
	for (it = lst.begin(); it != lst.end(); it++)
		cout << *it << " "; // 输出:8 9 9 9 2 4 5
	cout << endl;

	return 0;
}

删除元素

  • 头部删除元素:lst.pop_front();
  • 末尾删除元素:lst.pop_back();
  • 任意位置删除一个元素:lst.erase(iterator it);
  • 删除 [first,last] 之间的元素:lst.erase(iterator first, iterator last);
  • 清空所有元素:lst.clear();

其他函数

  • 多个元素赋值:lst.assign(int nSize, const T& x); // 类似于初始化时用数组进行赋值
  • 交换两个同类型容器的元素:swap(list&, list&); 或 lst.swap(list&);
  • 合并两个列表的元素(默认升序排列):lst.merge();
  • 在任意位置拼接入另一个list:lst.splice(iterator it, list&);
  • 删除容器中相邻的重复元素:lst.unique();
#include <iostream>
#include <list>

using namespace std;

int main(int argc, char* argv[])
{
	// 多个元素赋值s
	list<int> lst1;
	lst1.assign(3, 1);
	list<int> lst2;
	lst2.assign(3, 2);
    
	// 交换两个容器的元素
	// swap(lst1, lst2); // ok
	lst1.swap(lst2);
	// 遍历显示
	cout << "交换后的lst1: ";
	list<int>::iterator it;
	for (it = lst1.begin(); it!=lst1.end(); it++)
		cout << *it << " "; // 输出:2 2 2
	cout << endl;
    
	// 遍历显示
	cout << "交换后的lst2: ";
	for (it = lst2.begin(); it != lst2.end(); it++)
		cout << *it << " "; // 输出:1 1 1
	cout << endl;

	list<int> lst3;
	lst3.assign(3, 3);
	list<int> lst4;
	lst4.assign(3, 4);
	// 合并两个列表的元素
	lst4.merge(lst3); // 不是简单的拼接,而是会升序排列
	cout << "合并后的lst4: ";
	for (it = lst4.begin(); it != lst4.end(); it++)
		cout << *it << " "; // 输出:3 3 3 4 4 4
	cout << endl;

	list<int> lst5;
	lst5.assign(3, 5);
	list<int> lst6;
	lst6.assign(3, 6);
	// 在lst6的第2个元素处,拼接入lst5
	lst6.splice(++lst6.begin(), lst5);
	cout << "拼接后的lst6: ";
	for (it = lst6.begin(); it != lst6.end(); it++)
		cout << *it << " "; // 输出:6 5 5 5 6 6
	cout << endl;

	// 删除容器中相邻的重复元素
	list<int> lst7;
	lst7.push_back(1);
	lst7.push_back(1);
	lst7.push_back(2);
	lst7.push_back(2);
	lst7.push_back(3);
	lst7.push_back(2);
	lst7.unique();
	cout << "删除容器中相邻的重复元素后的lst7: ";
	for (it = lst7.begin(); it != lst7.end(); it++)
		cout << *it << " "; // 输出:1 2 3 2
	cout << endl;

	return 0;
}

迭代器与算法

迭代器

  • 开始迭代器指针:lst.begin();
  • 末尾迭代器指针:lst.end(); // 指向最后一个元素的下一个位置
  • 指向常量的开始迭代器指针:lst.cbegin(); // 意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
  • 指向常量的末尾迭代器指针:lst.cend();
  • 反向迭代器指针,指向最后一个元素:lst.rbegin();
  • 反向迭代器指针,指向第一个元素的前一个元素:lst.rend();

算法

遍历

list<int>::iterator it;
for (it = lst.begin(); it != lst.end(); it++)
    cout << *it << endl;

元素翻转

#include <algorithm>
reverse(lst.begin(), lst.end());

元素排列

#include <algorithm>
sort(lst.begin(), lst.end()); // 采用的是从小到大的排序

// 如果想从大到小排序,可以采用先排序后反转的方式,也可以采用下面方法:
// 自定义从大到小的比较器,用来改变排序方式
bool Comp(const int& a, const int& b) 
{
    return a > b;
}

sort(lst.begin(), lst.end(), Comp);

总结

可以看到,list 与 vector、deque 的用法基本一致,除了以下几处不同:

  • list 为双向迭代器,故不支持it+=i
  • list 不支持下标访问和at方法访问。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值