chapter_stack_and_queue/deque/ #140
Replies: 42 comments 68 replies
-
我想问一下K神,双向队列的具体操作体现在哪呢,我看大话数据结构中没有讲到这个,有点好奇它的实际应用,因为我细看了这一章节,更像是两个栈拼接在了一起 |
Beta Was this translation helpful? Give feedback.
-
// 当 i 越过数组头部后,回到尾部 |
Beta Was this translation helpful? Give feedback.
-
array_deque 队尾出队 popLast 方法不需要重设 rear 指针吗? |
Beta Was this translation helpful? Give feedback.
-
k神,基于双向链表的实现的图里,step4的popLast应该pop掉5吧? |
Beta Was this translation helpful? Give feedback.
-
def pop(self, is_front: bool) -> int: |
Beta Was this translation helpful? Give feedback.
-
我想请问一下这部分代码: |
Beta Was this translation helpful? Give feedback.
-
感觉这个地方会出bug啊 |
Beta Was this translation helpful? Give feedback.
-
/* 双向链表节点 */
class ListNode {
var val: Int // 节点值
var next: ListNode? // 后继节点引用(指针)
weak var prev: ListNode? // 前驱节点引用(指针)
init(val: Int) {
self.val = val
}
} 在Swift中为了避免循环引用,是不是加个 |
Beta Was this translation helpful? Give feedback.
-
return (i + capacity()) % capacity();这段代码我看了好久没明白,结果看到了front = index(front - 1);是这个原因吧 |
Beta Was this translation helpful? Give feedback.
-
原来如此啊,撤销功能用的竟然是双栈队列 |
Beta Was this translation helpful? Give feedback.
-
// 队首出队操作 大佬,我想请问下这段代码能不能替换成下面这样。 // 队首出队操作 |
Beta Was this translation helpful? Give feedback.
-
关于最后撤销的实现,那么恢复(CTRL + Y)操作是怎么实现的? |
Beta Was this translation helpful? Give feedback.
-
if (isFront) {
val = front->val; // 暂存头节点值
// 删除头节点
DoublyListNode *fNext = front->next;
if (fNext != nullptr) {
fNext->prev = nullptr;
front->next = nullptr;
delete front;
}
front = fNext; // 更新头节点
// 队尾出队操作
} else {
val = rear->val; // 暂存尾节点值
// 删除尾节点
DoublyListNode *rPrev = rear->prev;
if (rPrev != nullptr) {
rPrev->next = nullptr;
rear->prev = nullptr;
delete rear;
}
rear = rPrev; // 更新尾节点
} 关于这段代码中删除节点的部分,为什么删除节点前需要手动断开连接,而单链表删除节点前不需要手动断开,不手动断开的话会有什么影响? |
Beta Was this translation helpful? Give feedback.
-
在双向队列的pop函数中用if (fNext != null) { |
Beta Was this translation helpful? Give feedback.
-
Hi,作者你好,在阅读本节“双向链表实现双向队列”部分代码的时候,发现出队列的部分操作应该是有些问题的,如下代码中注释说明,如果确实有问题的话我后面commit一下代码: /*下面是本节用双向链表实现双向队列的出队操作,部分地方存在问题已经在注释中指出*/
/* 出队操作 */
int pop(bool isFront) {
if (isEmpty())
throw out_of_range("队列为空");
int val;
// 队首出队操作
if (isFront) {
val = front->val; // 暂存头节点值
// 删除头节点
DoublyListNode *fNext = front->next;
if (fNext != nullptr) {
fNext->prev = nullptr;
front->next = nullptr;
/*
* 下面这个地方delete的位置是不对的
* 假设只有一个节点,这个节点永远也不能被delete,应该放在if之外
*/
//delete front;
}
delete front;
front = fNext; // 更新头节点
// 队尾出队操作
} else {
val = rear->val; // 暂存尾节点值
// 删除尾节点
DoublyListNode *rPrev = rear->prev;
if (rPrev != nullptr) {
rPrev->next = nullptr;
rear->prev = nullptr;
/*原因同上*/
//delete rear;
}
delete rear;
rear = rPrev; // 更新尾节点
}
queSize--; // 更新队列长度
return val;
} |
Beta Was this translation helpful? Give feedback.
-
大佬,请问《5.3.2 双向队列实现*》中《1. 基于双向链表实现》js代码中有一行起到了什么作用? /* 队尾出队操作 */
popLast() {
if (this.#queSize === 0) {
return null;
}
const value = this.#rear.val; // 存储尾节点值
// 删除尾节点
let temp = this.#rear.prev;
if (temp !== null) {
temp.next = null;
this.#rear.prev = null; // ❓❓❓这一行作用是什么❓❓❓下面不是重新赋值更新尾节点了吗
}
this.#rear = temp; // 更新尾节点
this.#queSize--;
return value;
} |
Beta Was this translation helpful? Give feedback.
-
#include<iostream>
#include<vector>
using namespace std;
/*双向链表节点*/
struct DoubleListNode
{
int val; //节点值
DoubleListNode *next; //后继节点指针
DoubleListNode *prev; //前驱节点指针
DoubleListNode(int val_):val(val_),prev(nullptr),next(nullptr){}
};
/*基于双向链表实现的双向队列*/
class linklistDeque
{
private:
DoubleListNode *front,*rear;
int dequesize = 0;
public:
linklistDeque():front(nullptr),rear(nullptr){}
~linklistDeque()
{
cout<<"析构函数调用"<<endl;
/*遍历链表删除节点,释放内存*/
DoubleListNode *pre,*cur = front;
while(cur!=nullptr)
{
pre = cur;
cur = cur->next;
delete pre;
}
}
/*获取双向队列长度*/
int size()
{
return dequesize;
}
/*判断双向队列是否为空*/
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;
}
dequesize++;
}
/*队首入队*/
void push_head(int num)
{
push(num,true);
}
/*队尾入队*/
void push_tail(int num)
{
push(num,false);
}
/*出队操作*/
int pop(bool isfoot)
{
int val = 0;
if(isEmpty())
{
throw out_of_range("队列为空");
}
/*队首出队操作*/
if(isfoot)
{
val = front->val;
/*删除头结点*/
DoubleListNode * fnext = front->next;
if(fnext!=nullptr)
{
fnext->prev = nullptr;
front->next = nullptr;
}
delete front;
front = fnext;
}
/*队尾出队*/
else
{
val = rear->val;
/*删除尾节点*/
DoubleListNode *rPrev = rear->prev;
if(rPrev!=nullptr)
{
rPrev->next = nullptr;
rear->prev = nullptr;
}
delete rear;
rear = rPrev; // 更新尾节点
}
dequesize--;
return val;
}
/*队首出队*/
int popfirst()
{
return pop(true);
}
/*队尾出队*/
int poplast()
{
return pop(false);
}
/*访问队首元素*/
int peekfirst()
{
if(isEmpty())
{
throw out_of_range("双向队列为空");
}
return front->val;
}
/*访问队尾元素*/
int peeklast()
{
if(isEmpty())
{
throw out_of_range("双向队列为空");
}
return 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;
}
}; 上述队头队尾元素出队的那儿修改指针有部分问题,上述是修改好的代码 |
Beta Was this translation helpful? Give feedback.
-
linkedlist_deque.cpp |
Beta Was this translation helpful? Give feedback.
-
重复是指?? 感觉这个没问题呀 这个每次都释放得很好呀也没特殊情况的限制
?倚???窗听雨??
***@***.***
…------------------ 原始邮件 ------------------
发件人: ***@***.***>;
发送时间: 2024年3月2日(星期六) 中午11:03
收件人: ***@***.***>;
抄送: ***@***.***>; ***@***.***>;
主题: Re: [krahets/hello-algo] chapter_stack_and_queue/deque/ (Discussion #140)
调用popLast()貌似会重复释放内存
int main()
{
LinkedListDeque q;
q.pushLast(1);
q.pushLast(2);
q.pushLast(3);
cout << q.popLast();
cout << q.popLast();
cout << q.popLast();
system("pause"); return 0;
}
~LinkedListDeque() { // 遍历链表删除节点,释放内存 DoublyListNode *pre, *cur = front; while (cur != nullptr) { pre = cur; cur = cur->next; delete pre; //这里error } }
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
找到下一个节点 删除上一个节点没问题呀 直到下一个节点到NULL 此时删除完毕
… 调用popLast()貌似会重复释放内存
|
Beta Was this translation helpful? Give feedback.
-
java中基于双向链表的双向队列的pop操作,如果只有一个元素,front = fNext; // 更新头节点,此时front指向null,rear没有更新为null,而是仍旧指向pop出去的元素。 |
Beta Was this translation helpful? Give feedback.
-
基于队列实现中,array_deque.go // 计算队尾指针,指向队尾索引 + 1 将num添加至队首,这块应该有误,应该是队尾 |
Beta Was this translation helpful? Give feedback.
-
from collections import deque
# 初始化双向队列
deque: deque[int] = deque()
# 元素入队
deque.append(2) # 添加至队尾
deque.append(5)
deque.append(4)
deque.appendleft(3) # 添加至队首
deque.appendleft(1)
# 访问元素
front: int = deque[0] # 队首元素
rear: int = deque[-1] # 队尾元素
# 元素出队
pop_front: int = deque.popleft() # 队首元素出队
pop_rear: int = deque.pop() # 队尾元素出队
# 获取双向队列的长度
size: int = len(deque)
# 判断双向队列是否为空
is_empty: bool = len(deque) == 0 这段代码在vscode上跑不动,问题好像在于双向队列实例的名字跟类名是一样的,vscode无法识别,把实例名字改为deque—example就能运行了 |
Beta Was this translation helpful? Give feedback.
-
基于环形数组实现的双向队列,nums内部实际上所有数据都存在,并未直接删除,而是通过两个指针来限制其有效区间,使得有效区间外的数据为“失效数据”,这个是否可以添加注释以便更加通俗的理解? |
Beta Was this translation helpful? Give feedback.
-
array_deque.cpp里的 用return (i + capacity()) % capacity();和用return i % capacity(); 没有区别的吧? |
Beta Was this translation helpful? Give feedback.
-
判断是不是空队列,能不能用 if(queSize==0)来判断。书上都是 if (isEmpty())。 这有什么利弊吗? |
Beta Was this translation helpful? Give feedback.
-
双向队列只要维护好一个头结点一个尾节点,就不是一定要用双向链表实现。 |
Beta Was this translation helpful? Give feedback.
-
环形数组真的太秒啦!!! |
Beta Was this translation helpful? Give feedback.
-
有个问题:刚开始是空队列,然后入队1个元素,入队的时候c++代码只对front进行了维护,但是正因为只入队了一个元素,该元素即是队首也是队尾,是不是也应该对 rear 进行维护。 |
Beta Was this translation helpful? Give feedback.
-
chapter_stack_and_queue/deque/
一本动画图解、能运行、可提问的数据结构与算法入门书
https://www.hello-algo.com/chapter_stack_and_queue/deque/
Beta Was this translation helpful? Give feedback.
All reactions