mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 06:07:20 +08:00 
			
		
		
		
	Add C++ code for the linkedlist deque and array deque (#400)
This commit is contained in:
		
							
								
								
									
										157
									
								
								codes/cpp/chapter_stack_and_queue/array_deque.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								codes/cpp/chapter_stack_and_queue/array_deque.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,157 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: array_deque->cpp
 | 
			
		||||
 * Created Time: 2023-03-02
 | 
			
		||||
 * Author: Krahets (krahets@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "../include/include.hpp"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 基于环形数组实现的双向队列 */
 | 
			
		||||
class ArrayDeque {
 | 
			
		||||
private:
 | 
			
		||||
    vector<int> nums;  // 用于存储双向队列元素的数组
 | 
			
		||||
    int front;         // 队首指针,指向队首元素
 | 
			
		||||
    int queSize;       // 双向队列长度
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /* 构造方法 */
 | 
			
		||||
    ArrayDeque(int capacity) {
 | 
			
		||||
        nums.resize(capacity);
 | 
			
		||||
        front = queSize = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 获取双向队列的容量 */
 | 
			
		||||
    int capacity() {
 | 
			
		||||
        return nums.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 获取双向队列的长度 */
 | 
			
		||||
    int size() {
 | 
			
		||||
        return queSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 判断双向队列是否为空 */
 | 
			
		||||
    bool isEmpty() {
 | 
			
		||||
        return queSize == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 计算环形数组索引 */
 | 
			
		||||
    int index(int i) {
 | 
			
		||||
        // 通过取余操作实现数组首尾相连
 | 
			
		||||
        // 当 i 越过数组尾部后,回到头部
 | 
			
		||||
        // 当 i 越过数组头部后,回到尾部
 | 
			
		||||
        return (i + capacity()) % capacity();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队首入队 */
 | 
			
		||||
    void pushFirst(int num) {
 | 
			
		||||
        if (queSize == capacity()) {
 | 
			
		||||
            cout << "双向队列已满" << endl;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // 队首指针向左移动一位
 | 
			
		||||
        // 通过取余操作,实现 front 越过数组头部后回到尾部
 | 
			
		||||
        front = index(front - 1);
 | 
			
		||||
        // 将 num 添加至队首
 | 
			
		||||
        nums[front] = num;
 | 
			
		||||
        queSize++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队尾入队 */
 | 
			
		||||
    void pushLast(int num) {
 | 
			
		||||
        if (queSize == capacity()) {
 | 
			
		||||
            cout << "双向队列已满" << endl;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // 计算尾指针,指向队尾索引 + 1
 | 
			
		||||
        int rear = index(front + queSize);
 | 
			
		||||
        // 将 num 添加至队尾
 | 
			
		||||
        nums[rear] = num;
 | 
			
		||||
        queSize++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队首出队 */
 | 
			
		||||
    int pollFirst() {
 | 
			
		||||
        int num = peekFirst();
 | 
			
		||||
        // 队首指针向后移动一位
 | 
			
		||||
        front = index(front + 1);
 | 
			
		||||
        queSize--;
 | 
			
		||||
        return num;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队尾出队 */
 | 
			
		||||
    int pollLast() {
 | 
			
		||||
        int num = peekLast();
 | 
			
		||||
        queSize--;
 | 
			
		||||
        return num;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 访问队首元素 */
 | 
			
		||||
    int peekFirst() {
 | 
			
		||||
        if (isEmpty())
 | 
			
		||||
            throw out_of_range("双向队列为空");
 | 
			
		||||
        return nums[front];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 访问队尾元素 */
 | 
			
		||||
    int peekLast() {
 | 
			
		||||
        if (isEmpty())
 | 
			
		||||
            throw out_of_range("双向队列为空");
 | 
			
		||||
        // 计算尾元素索引
 | 
			
		||||
        int last = index(front + queSize - 1);
 | 
			
		||||
        return nums[last];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 返回数组用于打印 */
 | 
			
		||||
    vector<int> toVector() {
 | 
			
		||||
        // 仅转换有效长度范围内的列表元素
 | 
			
		||||
        vector<int> res(queSize);
 | 
			
		||||
        for (int i = 0, j = front; i < queSize; i++, j++) {
 | 
			
		||||
            res[i] = nums[index(j)];
 | 
			
		||||
        }
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Driver Code */
 | 
			
		||||
int main() {
 | 
			
		||||
    /* 初始化双向队列 */
 | 
			
		||||
    ArrayDeque *deque = new ArrayDeque(10);
 | 
			
		||||
    deque->pushLast(3);
 | 
			
		||||
    deque->pushLast(2);
 | 
			
		||||
    deque->pushLast(5);
 | 
			
		||||
    cout << "双向队列 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
 | 
			
		||||
    /* 访问元素 */
 | 
			
		||||
    int peekFirst = deque->peekFirst();
 | 
			
		||||
    cout << "队首元素 peekFirst = " << peekFirst << endl;
 | 
			
		||||
    int peekLast = deque->peekLast();
 | 
			
		||||
    cout << "队尾元素 peekLast = " << peekLast << endl;
 | 
			
		||||
 | 
			
		||||
    /* 元素入队 */
 | 
			
		||||
    deque->pushLast(4);
 | 
			
		||||
    cout << "元素 4 队尾入队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
    deque->pushFirst(1);
 | 
			
		||||
    cout << "元素 1 队首入队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
 | 
			
		||||
    /* 元素出队 */
 | 
			
		||||
    int pollLast = deque->pollLast();
 | 
			
		||||
    cout << "队尾出队元素 = " << pollLast << ",队尾出队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
    int pollFirst = deque->pollFirst();
 | 
			
		||||
    cout << "队首出队元素 = " << pollFirst << ",队首出队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
 | 
			
		||||
    /* 获取双向队列的长度 */
 | 
			
		||||
    int size = deque->size();
 | 
			
		||||
    cout << "双向队列长度 size = " << size << endl;
 | 
			
		||||
 | 
			
		||||
    /* 判断双向队列是否为空 */
 | 
			
		||||
    bool isEmpty = deque->isEmpty();
 | 
			
		||||
    cout << "双向队列是否为空 = " << boolalpha << isEmpty << endl;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										188
									
								
								codes/cpp/chapter_stack_and_queue/linkedlist_deque.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								codes/cpp/chapter_stack_and_queue/linkedlist_deque.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,188 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: linkedlist_deque->cpp
 | 
			
		||||
 * Created Time: 2023-03-02
 | 
			
		||||
 * Author: Krahets (krahets@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "../include/include.hpp"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 双向链表结点 */
 | 
			
		||||
struct DoubleListNode {
 | 
			
		||||
    int val;               // 结点值
 | 
			
		||||
    DoubleListNode *next;  // 后继结点指针
 | 
			
		||||
    DoubleListNode *prev;  // 前驱结点指针
 | 
			
		||||
    DoubleListNode(int val) : val(val), prev(nullptr), next(nullptr) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 基于双向链表实现的双向队列 */
 | 
			
		||||
class LinkedListDeque {
 | 
			
		||||
private:
 | 
			
		||||
    DoubleListNode *front, *rear; // 头结点 front ,尾结点 rear
 | 
			
		||||
    int queSize = 0;              // 双向队列的长度
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /* 构造方法 */
 | 
			
		||||
    LinkedListDeque() : front(nullptr), rear(nullptr) {}
 | 
			
		||||
 | 
			
		||||
    /* 析构方法 */
 | 
			
		||||
    ~LinkedListDeque() {
 | 
			
		||||
        // 释放内存
 | 
			
		||||
        DoubleListNode *pre, *cur = front;
 | 
			
		||||
        while (cur != nullptr) {
 | 
			
		||||
            pre = cur;
 | 
			
		||||
            cur = cur->next;
 | 
			
		||||
            delete pre;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 获取双向队列的长度 */
 | 
			
		||||
    int size() {
 | 
			
		||||
        return queSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 判断双向队列是否为空 */
 | 
			
		||||
    bool isEmpty() {
 | 
			
		||||
        return size() == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 入队操作 */
 | 
			
		||||
    void push(int num, bool isFront) {
 | 
			
		||||
        DoubleListNode *node = new DoubleListNode(num);
 | 
			
		||||
        // 若链表为空,则令 front, rear 都指向 node
 | 
			
		||||
        if (isEmpty())
 | 
			
		||||
            front = rear = node;
 | 
			
		||||
        // 队首入队操作
 | 
			
		||||
        else if (isFront) {
 | 
			
		||||
            // 将 node 添加至链表头部
 | 
			
		||||
            front->prev = node;
 | 
			
		||||
            node->next = front;
 | 
			
		||||
            front = node; // 更新头结点
 | 
			
		||||
        // 队尾入队操作
 | 
			
		||||
        } else {
 | 
			
		||||
            // 将 node 添加至链表尾部
 | 
			
		||||
            rear->next = node;
 | 
			
		||||
            node->prev = rear;
 | 
			
		||||
            rear = node;  // 更新尾结点
 | 
			
		||||
        }
 | 
			
		||||
        queSize++; // 更新队列长度
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队首入队 */
 | 
			
		||||
    void pushFirst(int num) {
 | 
			
		||||
        push(num, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队尾入队 */
 | 
			
		||||
    void pushLast(int num) {
 | 
			
		||||
        push(num, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 出队操作 */
 | 
			
		||||
    int poll(bool isFront) {
 | 
			
		||||
        // 若队列为空,直接返回 -1
 | 
			
		||||
        if (isEmpty())
 | 
			
		||||
            return -1;
 | 
			
		||||
        int val;
 | 
			
		||||
        // 队首出队操作
 | 
			
		||||
        if (isFront) {
 | 
			
		||||
            val = front->val; // 暂存头结点值
 | 
			
		||||
            // 删除头结点
 | 
			
		||||
            DoubleListNode *fNext = front->next;
 | 
			
		||||
            if (fNext != nullptr) {
 | 
			
		||||
                fNext->prev = nullptr;
 | 
			
		||||
                front->next = nullptr;
 | 
			
		||||
            }
 | 
			
		||||
            front = fNext;   // 更新头结点
 | 
			
		||||
        // 队尾出队操作
 | 
			
		||||
        } else {
 | 
			
		||||
            val = rear->val; // 暂存尾结点值
 | 
			
		||||
            // 删除尾结点
 | 
			
		||||
            DoubleListNode *rPrev = rear->prev;
 | 
			
		||||
            if (rPrev != nullptr) {
 | 
			
		||||
                rPrev->next = nullptr;
 | 
			
		||||
                rear->prev = nullptr;
 | 
			
		||||
            }
 | 
			
		||||
            rear = rPrev;    // 更新尾结点
 | 
			
		||||
        }
 | 
			
		||||
        queSize--; // 更新队列长度
 | 
			
		||||
        return val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队首出队 */
 | 
			
		||||
    int pollFirst() {
 | 
			
		||||
        return poll(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队尾出队 */
 | 
			
		||||
    int pollLast() {
 | 
			
		||||
        return poll(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 访问队首元素 */
 | 
			
		||||
    int peekFirst() {
 | 
			
		||||
        return isEmpty() ? -1 : front->val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 访问队尾元素 */
 | 
			
		||||
    int peekLast() {
 | 
			
		||||
        return isEmpty() ? -1 : rear->val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 返回数组用于打印 */
 | 
			
		||||
    vector<int> toVector() {
 | 
			
		||||
        DoubleListNode *node = front;
 | 
			
		||||
        vector<int> res(size());
 | 
			
		||||
        for (int i = 0; i < res.size(); i++) {
 | 
			
		||||
            res[i] = node->val;
 | 
			
		||||
            node = node->next;
 | 
			
		||||
        }
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Driver Code */
 | 
			
		||||
int main() {
 | 
			
		||||
    /* 初始化双向队列 */
 | 
			
		||||
    LinkedListDeque *deque = new LinkedListDeque();
 | 
			
		||||
    deque->pushLast(3);
 | 
			
		||||
    deque->pushLast(2);
 | 
			
		||||
    deque->pushLast(5);
 | 
			
		||||
    cout << "双向队列 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
 | 
			
		||||
    /* 访问元素 */
 | 
			
		||||
    int peekFirst = deque->peekFirst();
 | 
			
		||||
    cout << "队首元素 peekFirst = " << peekFirst << endl;
 | 
			
		||||
    int peekLast = deque->peekLast();
 | 
			
		||||
    cout << "队尾元素 peekLast = " << peekLast << endl;
 | 
			
		||||
 | 
			
		||||
    /* 元素入队 */
 | 
			
		||||
    deque->pushLast(4);
 | 
			
		||||
    cout << "元素 4 队尾入队后 deque =" ;
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
    deque->pushFirst(1);
 | 
			
		||||
    cout << "元素 1 队首入队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
 | 
			
		||||
    /* 元素出队 */
 | 
			
		||||
    int pollLast = deque->pollLast();
 | 
			
		||||
    cout << "队尾出队元素 = " << pollLast << ",队尾出队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
    int pollFirst = deque->pollFirst();
 | 
			
		||||
    cout << "队首出队元素 = " << pollFirst << ",队首出队后 deque = ";
 | 
			
		||||
    PrintUtil::printVector(deque->toVector());
 | 
			
		||||
 | 
			
		||||
    /* 获取双向队列的长度 */
 | 
			
		||||
    int size = deque->size();
 | 
			
		||||
    cout << "双向队列长度 size = " << size << endl;
 | 
			
		||||
 | 
			
		||||
    /* 判断双向队列是否为空 */
 | 
			
		||||
    bool isEmpty = deque->isEmpty();
 | 
			
		||||
    cout << "双向队列是否为空 = " << boolalpha << isEmpty << endl;
 | 
			
		||||
 | 
			
		||||
    // 释放内存
 | 
			
		||||
    delete deque;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -8,9 +8,9 @@ import (
 | 
			
		||||
	"container/list"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* 基于链表实现的双端队列 */
 | 
			
		||||
/* 基于双向链表实现的双向队列 */
 | 
			
		||||
type linkedListDeque struct {
 | 
			
		||||
	// 使用内置包 list 来实现栈
 | 
			
		||||
	// 使用内置包 list
 | 
			
		||||
	data *list.List
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ class ListNode {
 | 
			
		||||
/* 基于双向链表实现的双向队列 */
 | 
			
		||||
class LinkedListDeque {
 | 
			
		||||
    private ListNode front, rear; // 头结点 front ,尾结点 rear
 | 
			
		||||
    private int size = 0;         // 双向队列的长度
 | 
			
		||||
    private int queSize = 0;      // 双向队列的长度
 | 
			
		||||
 | 
			
		||||
    public LinkedListDeque() {
 | 
			
		||||
        front = rear = null;
 | 
			
		||||
@ -30,7 +30,7 @@ class LinkedListDeque {
 | 
			
		||||
 | 
			
		||||
    /* 获取双向队列的长度 */
 | 
			
		||||
    public int size() {
 | 
			
		||||
        return size;
 | 
			
		||||
        return queSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 判断双向队列是否为空 */
 | 
			
		||||
@ -57,7 +57,7 @@ class LinkedListDeque {
 | 
			
		||||
            node.prev = rear;
 | 
			
		||||
            rear = node;  // 更新尾结点
 | 
			
		||||
        }
 | 
			
		||||
        size++; // 更新队列长度
 | 
			
		||||
        queSize++; // 更新队列长度
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 队首入队 */
 | 
			
		||||
@ -97,7 +97,7 @@ class LinkedListDeque {
 | 
			
		||||
            }
 | 
			
		||||
            rear = rPrev;    // 更新尾结点
 | 
			
		||||
        }
 | 
			
		||||
        size--; // 更新队列长度
 | 
			
		||||
        queSize--; // 更新队列长度
 | 
			
		||||
        return val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user