片方向リストの C++ コピー コンストラクター
この記事では、まず、リンク リスト データ構造の概念と、それを使用するための適切なシナリオについて説明します。 次に、単一リストのコンパクトな実装と、C++ を使用した単一リンク リストのコピー コンストラクターについて説明します。
C++ リンク リスト データ構造
リンク リスト データ構造の主な利点は、連続していないメモリ位置にデータを格納できることです。 これはノードで構成される線形データ構造であり、各ノードにはデータ項目 (キーおよび関連する衛星データ) と次のノードへの参照が格納されます。
ヘッド ポインターは、このデータ構造の最初のノードを指します。 そのため、ヘッド ノードと呼ばれることもあります。 片方向リストの一部の古典的な実装には、リストの最後のノードを指すテール ポインターもあります。
たとえば、次の図は、テール ポインターのないリンク リストの概念の例を示しています。
リンク リストには次の 3つのタイプがあります。
-
単独連結リストまたは単純連結リスト
これは単純な Linked List であり、Singly Linked List とも呼ばれ、前にしか進めません。 各ノードには、データ項目と次のノードの参照が格納されます。
-
二重連結リスト
これは、前後に移動できるリンク リストです。 二重連結リスト の各ノードは、データ項目、次のノードの参照、および前のノードの参照で構成されます。
これは、Web ブラウザーの次のページや前のナビゲーションなど、do/redo 状態のシナリオでバッターに適しています。
-
循環リンクリスト
リストの最後のノードの次のポインタが常に最初のノードを指していることを除いて、Singly Linked List とほとんど同じです。 これにより円が作成されます。 したがって、循環リンク リストと呼ばれます。
通常、循環キュー管理システムで便利です。
片方向リストのコード例
単一リンク リストの次の C++ 実装を見てみましょう。
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
};
class LinkedList {
public:
Node* head;
LinkedList() { head = nullptr; }
void addNewItem(int data) {
Node* temp = new Node();
temp->data = data;
temp->next = head;
head = temp;
}
void display() {
Node* temp = head;
while (temp != nullptr) {
cout << temp->data << ",";
temp = temp->next;
}
cout << endl;
}
};
int main() {
LinkedList list;
list.addNewItem(5);
list.addNewItem(10);
list.addNewItem(15);
list.display();
return 0;
}
上記のコードは、次のクラスで構成されています。
- 2つのメンバー変数を持つクラス
Node
:data
とNode
クラス ポインターnext
。data
変数は要素の値を格納するために使用され、next
変数は次の要素の参照を格納するために使用されます。 - クラス
LinkedList
には、リンク リストの最初の要素を格納するために使用される型Node
のメンバ変数head
、コンストラクタLinkedList()
、および 2つのメンバ関数addNewItem
とdisplay() があります。
.LinkedList()
コンストラクターは、ヘッドを null 値で初期化します。
addNewItem
メソッドは、リンク リストの先頭に新しい要素を追加するために使用されます。 この関数に AddToFront
または push
という名前を付けることもできます。
display()
メソッドは、リンクされたリストの要素を表示します。
C++ 単方向リンク リストのコピー コンストラクター
以下は、単一リンク リストのコピー コンストラクターのコードです。
LinkedList(const LinkedList& obj) {
if (obj.head != nullptr) {
this->head = new Node;
this->head->data = obj.head->data;
Node* temp = obj.head->next;
Node* temp2 = this->head;
while (temp != nullptr) {
Node* newNode = new Node; ////
newNode->data = temp->data; //// creating new node
newNode->next = temp->next; ////
temp2->next = newNode;
temp2 = temp2->next;
temp = temp->next;
}
} else {
head = nullptr;
}
}
上記のコードは、リンク リスト オブジェクト const LinkedList &obj
をパラメーターとして受け取り、受け取ったリンク リストのすべてのデータを呼び出し元のリンク リストにコピーする単独リンク リスト コピー コンストラクターを示しています。
Linked List は Node
型ポインターを使用するため、ディープ コピーのコピー コンストラクターを定義する必要があります。 コピー コンストラクターの実装が提供されていない場合、浅いコピーが作成されます。
コピー コンストラクターの呼び出し
次の main()
関数のコードを考えてみましょう:
int main() {
LinkedList list; // Declaring a List
list.addNewItem(5);
list.addNewItem(10);
list.addNewItem(15);
cout << "The content of List 1 are: ";
list.display();
LinkedList list2(list); // Declaring a list2 with the copy constructor
cout << "The content of List 2 are: ";
list2.display();
return 0;
}
上記のコードでは、LinkedList
タイプのオブジェクト list
が LinkedList list;
を使用して作成されます。 声明。 この後、list.addNewItem( )
メソッドを使用して 3つの値をリストに挿入しました。
LinkedList
型の list2
の別のオブジェクトが作成され、最初の list
オブジェクトを宣言時にパラメーターとして渡して、コピー コンストラクターを呼び出します。 両方のオブジェクトの display()
メソッドは、リストに同じデータ項目を表示します。
出力: