我现在开始为我的班级跳入C++,我们在 Scheme 中介绍了排队和取消排队。但是,我们现在正在C++中这样做,我们需要使用指针,我正在努力理解。我了解什么是指针,何时使用它们等。但是,我正在努力弄清楚如何在此实验室中实现它们。我目前有这个代码:
#include <stdlib.h>
#include <iostream>
#include <assert.h>
using namespace std;
struct node {
int item;
node* next;
};
typedef node* nodePtr;
typedef nodePtr* queue;
queue makeQueue() {
queue q = new nodePtr[2];
q[0] = NULL;
q[1] = NULL;
return q;
}
nodePtr start(queue q) {
return q[0];
}
nodePtr tail(queue q) {
return q[1];
}
void setStart(queue q, nodePtr newNode) {
q[0] = newNode;
}
void setTail(queue q, nodePtr newNode) {
q[1] = newNode;
}
bool emptyQueue(queue q) {
return q[0] == NULL;
}
int head(queue q) {
if (emptyQueue(q)) {
cout << "Attempt to take head of an empty queue.n";
exit(1);
}
return start(q)->item;
}
void enqueue(queue q, int newItem) {
// Answer goes here.
}
void dequeue(queue q) {
// Answer goes here.
}
对于这段代码,我明白我需要做什么:排队会将 newItem 推送到队列的 cdr(或尾部(上,而 Dequeue 将在队列开始时删除节点,并相应地更新适当的位置。但真正让我感到困惑的只是指针,我不知道该怎么办。
我将如何潜入编写带有指针的排队和取消排队?我将茫然地假设排队和取消排队不应该是一行又一行的代码。
非常感谢!
在处理基于指针的动态结构(如堆栈、链表和队列(时,一切都是关于重新排列指针。正如评论中所建议的那样,将指针表示为纸上指向节点的箭头将有助于可视化在 en-/dequeuing 时需要如何重新分配指针。
我还想指出,您不应该像以前那样混合使用 C 和 C++ 标头。C++库包含与在头文件相同结构中组织的 C 语言库相同的定义。每个头文件的名称与 C 语言版本相同,但带有"c"前缀且没有扩展名。例如,C语言头文件<stdlib.h>
的C++等效项是<cstdlib>
,同样,<assert.h>
是<cassert>
。此外,在C++中,NULL 指针nullptr
;混合NULL
和nullptr
可能会在使用int
和指针参数重载函数时导致问题。
现在谈谈眼前的问题。每个node
都有一个成员next
,这是一个指向队列中下一个node
的箭头。看起来,q[0]
和q[1]
是第一个和最后一个元素的相应箭头。
如果只想从有效负载数据(而不是完整node
(中排队新元素,则必须首先动态创建node
对象。然后,它的next
指针必须指向q[0]->next
指向的内容,而q[0]->next
必须重新分配以指向您刚刚创建的新节点:
以前:
q[0]->next ---> somenode
后:
q[0]->next -. -XXX-> somenode
| ^
| |
'-> newnode->next -'
或C++(未经验证(:
void enqueue(queue q, int newItem) {
nodePtr newnode = new node;
newnode->item = newItem;
newnode->next = q[0]->next;
q[0]->next = newnode;
}
出队相应地进行,只需查看您需要如何重新排列指针即可。不要忘记delete
删除的节点,并提供一个功能来删除makeQueue
创建的queue
。