【发布时间】:2011-10-10 18:16:00
【问题描述】:
我正在研究 C++ 中的链表实现。我正在取得进展,但无法让插入功能和删除功能正常工作。下面是 C++ 头文件中的列表对象:
#ifndef linkList_H
#define linkList_h
//
// Create an object to represent a Node in the linked list object
// (For now, the objects to be put in the list will be integers)
//
struct Node
{
Node() : sentinel(0) {}
int number;
Node* next;
Node* prev;
Node* sentinel;
};
//
// Create an object to keep track of all parts in the list
//
class List
{
public:
//
// Contstructor intializes all member data
//
List() : m_listSize(0), m_listHead(0) {}
//
// methods to return size of list and list head
//
Node* getListHead() const { return m_listHead; }
unsigned getListSize() const { return m_listSize; }
//
// method for adding and inserting a new node to the linked list,
// retrieving and deleting a specified node in the list
//
void addNode(int num);
void insertNode(Node* current);
void deleteNode(Node* current);
Node* retrieveNode(unsigned position);
private:
//
// member data consists of an unsigned integer representing
// the list size and a pointer to a Node object representing head
//
Node* m_listHead;
unsigned m_listSize;
};
#endif
这是实现(.cpp)文件:
#include "linkList.h"
#include <iostream>
using namespace std;
//
// Adds a new node to the linked list
//
void List::addNode(int num)
{
Node *newNode = new Node;
newNode->number = num;
newNode->next = m_listHead;
m_listHead = newNode;
++m_listSize;
}
//
// NOTWORKING: Inserts a node which has already been set to front
// of the list
//
void List::insertNode(Node* current)
{
// check to see if current node already at
// head of list
if(current == m_listHead)
return;
current->next = m_listHead;
if(m_listHead != 0)
m_listHead->prev = current;
m_listHead = current;
current->prev = 0;
}
//
// NOTWORKING: Deletes a node from a specified position in linked list
//
void List::deleteNode(Node* current)
{
current->prev->next = current->next;
current->next->prev = current->prev;
}
//
// Retrieves a specified node from the list
//
Node* List::retrieveNode(unsigned position)
{
if(position > (m_listSize-1) || position < 0)
{
cout << "Can't access node; out of list bounds";
cout << endl;
cout << endl;
exit(EXIT_FAILURE);
}
Node* current = m_listHead;
unsigned pos = 0;
while(current != 0 && pos != position)
{
current = current->next;
++pos;
}
return current;
}
在客户端 C++ 代码中运行一个简短的测试程序后,输出结果如下:
Number of nodes: 10
Elements in each node:
9 8 7 6 5 4 3 2 1 0
Insertion of node 5 at the list head:
4 9 8 7 6 5 4 9 8 7
Deletion of node 5 from the linked list
如您所见,插入不仅仅是将节点 5 移动到列表的头部,而是从第三个位置开始覆盖其他节点。我尝试实现的伪代码来自麻省理工学院算法书:
LIST-INSERT(L, x)
next[x] <- head[L]
if head[L] != NIL
then prev[head[L]] <- x
head[L] <- x
prev[x] <- NIL
当调用该方法时,删除实现也会崩溃。不知道为什么;但这里是对应的伪代码:
LIST-DELET'
next[prev[x]] <- next[x]
prev[next[x]] <- prev[x]
说实话,我不确定前一个、下一个和哨兵指针是如何在内存中实际工作的。我知道他们在实际意义上应该做什么,但是看看调试器,在删除的情况下,这些指针似乎没有指向任何东西:
(*current).prev 0xcdcdcdcd {number=??? next=??? prev=??? ...} Node *
number CXX0030: Error: expression cannot be evaluated
next CXX0030: Error: expression cannot be evaluated
prev CXX0030: Error: expression cannot be evaluated
sentinel CXX0030: Error: expression cannot be evaluated
任何帮助将不胜感激!
【问题讨论】:
-
我很惊讶每个节点都有一个哨兵节点...嗯...
-
你知道标准库中已经存在单链表和双链表了吗?
-
我知道 STL 并喜欢使用它,但这是我的数据结构类的作业,不允许使用 STL。
-
@Dylan:那么请将作业标记为作业,以便人们知道我们在处理什么。 任何标签不如“homework”标签重要。
标签: c++ algorithm linked-list