[英]Inserting into a Doubly Linked List
我正在嘗試為項目創建一個雙向鏈接列表容器。 我不能使用任何標准容器。 雙鏈列表必須進行排序。 到目前為止,這是我的代碼:
#include <iostream>
using namespace std;
template <typename T>
class dll {
private:
struct Node {
Node* prev;
Node* next;
T data;
};
Node* head;
Node* tail;
public:
dll();
~dll();
void insert(T value);
bool empty() const { return head == tail; };
};
template <typename T> dll<T>::dll() {
head = nullptr;
tail = head;
}
template <typename T> dll<T>::~dll() {
delete[] head;
}
template <typename T> void dll<T>::insert(T value) {
Node *node = new Node;
node->data = value;
// Case 1: There are no nodes yet
if (head == nullptr) {
node->prev = nullptr;
node->next = nullptr;
head = node;
tail = head;
}
else {
// Case 2: There is more than one node
Node *curr = head;
if (curr->next != nullptr)
{
while (curr->next) {
// If the value is less than the current value
if (value < curr->data) {
Node *temp = new Node;
temp->data = curr->data;
temp->next = curr->next;
temp->prev = curr->prev;
node->next = temp;
node->prev = temp->prev;
curr->prev = node;
}
curr = curr->next;
}
}
// Case 3: There is only one node
else {
node->prev = head;
node->next = nullptr;
tail = node;
}
}
}
int main() {
dll<int> list;
list.insert(10);
list.insert(20);
list.insert(15);
}
我遇到的問題是我的插入功能。 我正在使用調試器,並進入以下代碼行:list.insert(10);。
它正確進入了head == nullptr的第一種情況,並創建了Node。 當我進入下一行代碼(list.insert(20))時,它將創建帶有以下行的節點:Node * node = new Node; 但是它正在使用頭指向的內存地址創建節點。
我觀察一下head變量,node變量和內存地址是相同的,基本上它創建的節點與上次插入相同。
我不知道該怎么做:Node * code = new Node; 創造新的東西。 我在這里使用新關鍵字錯誤嗎?
為了簡化Node的初始化,讓我們添加一個合理的構造函數,將prev和next成員初始化為null。 這使得以后的代碼變得更容易。
struct Node {
Node* prev;
Node* next;
T data;
Node() : prev(nullptr), next(nullptr)
{
}
};
鏈表問題中始終有四種情況需要注意。 你有一些。 插入一個空列表。 在列表的前面插入,在列表的末尾和中間插入。
template <typename T> void dll<T>::insert(T value) {
Node *node = new Node;
node->data = value;
// Case 1: There are no nodes yet
if (head == nullptr) {
head = node;
tail = head;
return;
}
// case 2 - inserting at the head of the list
if (node->data < head->data)
{
node->next = head;
head = node;
return;
}
// case 3 - inserting at the end of the list
if (node->data >= tail->data)
{
node->prev = tail;
tail->next = node;
tail = node;
return;
}
// general case - inserting into the middle
Node* probe = head;
while (probe && (node->data >= probe->data))
{
probe = probe->next;
}
if (probe)
{
node->next = probe;
node->prev = probe->prev;
probe->prev->next = node;
probe->prev = node;
return;
}
// error - we shouldnt' reach this point. If we did, it meant the list was out of order to begin with.
return;
}
首先,析構函數是無效的。 這個說法
delete[] head;
表示head是一個數組。 但是head不是數組。 它是指向Node類型的單個對象的指針。 您必須刪除析構函數中列表的所有節點。 析構函數可以如下所示
template <typename T>
dll<T>::~dll()
{
while ( head )
{
Node *tmp = head;
head = head->next;
delete tmp;
}
}
至於方法插入,則它看起來非常簡單。 例如
template <typename T>
void dll<T>::insert( const T &value )
{
Node *current = head;
Node *previous = nullptr;
while ( current && !( value < current->data ) )
{
previous = current;
current = current->next;
}
Node *node = new Node { previous, current, value };
if ( previous == nullptr ) head = node;
else previous->next = node;
if ( current == nullptr ) tail = node;
else current->prev = node;
}
並且沒有任何必要和理由添加構造器來構造Node。 匯總時會更好。
這是一個測試程序
#include <iostream>
template <typename T>
class dll
{
private:
struct Node
{
Node *prev;
Node *next;
T data;
};
Node *head;
Node *tail;
public:
dll();
~dll();
void insert( const T &value);
bool empty() const { return head == tail; };
void print() const;
};
template <typename T>
dll<T>::dll()
{
head = tail = nullptr;
}
template <typename T>
dll<T>::~dll()
{
while ( head )
{
Node *tmp = head;
head = head->next;
delete tmp;
}
}
template <typename T>
void dll<T>::insert( const T &value )
{
Node *current = head;
Node *previous = nullptr;
while ( current && !( value < current->data ) )
{
previous = current;
current = current->next;
}
Node *node = new Node { previous, current, value };
if ( previous == nullptr ) head = node;
else previous->next = node;
if ( current == nullptr ) tail = node;
else current->prev = node;
}
template <typename T>
void dll<T>::print() const
{
for ( Node *current = head; current; current = current->next )
{
std::cout << current->data << ' ';
}
}
int main()
{
dll<int> list;
list.insert( 10 );
list.insert( 20 );
list.insert( 15 );
list.print();
std::cout << std::endl;
return 0;
}
輸出是
10 15 20
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.