단일 연결 목록 C++에 노드 삽입
이 기사에서는 C++의 단일 연결 목록에 새 노드를 삽입하는 방법을 설명합니다.
연결된 목록의 끝에 노드를 삽입하는 함수 구현
연결된 목록은 순차적으로 서로를 가리키는 노드로 구성된 선형 데이터 구조입니다. 이 기사에서는 단일 연결 목록 구조에 더 초점을 맞추고 그에 따라 여러 삽입 작업을 구현합니다.
단일 연결 목록에는 데이터 개체와 목록의 다음 노드에 대한 포인터가 있습니다. 목록 삽입 작업을 더 잘 보여주기 위해ListNode
라는 노드 구조와 두 개의 도우미 함수 (freeNodes
및printNodes
)를 정의했습니다. 삽입 작업 시간 복잡도는 노드를 삽입하는 위치에 따라 다릅니다. 예를 들어, 목록의 끝을 알 수없는 경우 목록 끝에 삽입하는 데 선형 시간이 걸립니다.
반면에 처음에 새 노드를 삽입하는 것은 항상 일정한 시간이 걸립니다. 다음 코드는 목록을 구성하는 핵심 함수로 취급 할 수있는insertNodeEnd
함수를 보여줍니다. 목록의 헤드를 첫 번째 매개 변수로 사용하고 새 노드에 저장해야하는string
데이터를 사용합니다. 이 함수는 목록의 첫 번째 요소를 만들고 그 끝에 새 요소를 추가 할 수 있습니다. 이 함수는 여유 저장 메모리에 새 노드를 할당합니다. 따라서freeNodes
기능은 프로그램 종료 전에 모든 메모리를 해제하는 데 필요합니다.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
struct ListNode {
struct ListNode *next{};
string data;
};
struct ListNode *insertNodeEnd(struct ListNode *root, string data) {
auto new_node = new ListNode;
if (root) {
while (root->next) root = root->next;
new_node->next = nullptr;
new_node->data = std::move(data);
root->next = new_node;
return root->next;
}
new_node->next = nullptr;
new_node->data = std::move(data);
return new_node;
}
void freeNodes(struct ListNode *root) {
struct ListNode *tmp = nullptr;
while (root) {
tmp = root;
root = root->next;
delete tmp;
}
}
void printNodes(struct ListNode *node) {
auto count = 0;
while (node) {
cout << "node " << count << " - data: " << node->data << endl;
node = node->next;
count++;
}
}
int main() {
struct ListNode *head = nullptr;
vector<string> data_set = {"Precise", "Quantal", "Saucy", "Raring"};
head = insertNodeEnd(head, data_set.at(0));
for (auto it = data_set.begin() + 1; it != data_set.end(); ++it) {
insertNodeEnd(head, *it);
}
printNodes(head);
cout << " ----------------------------------- " << endl;
insertNodeEnd(head, "Utopic");
printNodes(head);
freeNodes(head);
return EXIT_SUCCESS;
}
출력:
node 0 - data: Precise
node 1 - data: Quantal
node 2 - data: Saucy
node 3 - data: Raring
-----------------------------------
node 0 - data: Precise
node 1 - data: Quantal
node 2 - data: Saucy
node 3 - data: Raring
node 4 - data: Utopic
연결된 목록에서 주어진 노드 뒤에 노드를 삽입하는 함수 구현
목록 중간에 노드를 삽입하려면 일반적으로 일정한 시간과 주어진 위치를 찾는 데 사용되는 검색 알고리즘의 시간 복잡성이 필요합니다. 그러나 검색 기능이 별도로 구현되었다고 가정하고insertNodeAfter
함수를 구성하여 대상 노드의 위치를 첫 번째 인수로 제공해야합니다.
insertNodeEnd
함수는 새로 추가 된 노드에 대한 포인터를 반환하므로 반환 값을 사용하여insertNodeAfter
의 작업을 보여줍니다. 임의의 위치 삽입을 위해 별도의 검색 기능이 필요하며 링크 된 목록에서 더 빠른 검색 작업을 구현하기 위해 외부 데이터 구조가 필요할 수도 있습니다.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
struct ListNode {
struct ListNode *next{};
string data;
};
struct ListNode *insertNodeEnd(struct ListNode *root, string data) {
auto new_node = new ListNode;
if (root) {
while (root->next) root = root->next;
new_node->next = nullptr;
new_node->data = std::move(data);
root->next = new_node;
return root->next;
}
new_node->next = nullptr;
new_node->data = std::move(data);
return new_node;
}
struct ListNode *insertNodeAfter(struct ListNode *prev, string data) {
if (!prev) return nullptr;
auto new_node = new ListNode;
new_node->next = nullptr;
new_node->data = std::move(data);
prev->next = new_node;
return new_node;
}
void freeNodes(struct ListNode *root) {
struct ListNode *tmp = nullptr;
while (root) {
tmp = root;
root = root->next;
delete tmp;
}
}
void printNodes(struct ListNode *node) {
auto count = 0;
while (node) {
cout << "node " << count << " - data: " << node->data << endl;
node = node->next;
count++;
}
}
int main() {
struct ListNode *head = nullptr;
vector<string> data_set = {"Precise", "Quantal", "Saucy", "Raring"};
head = insertNodeEnd(head, data_set.at(0));
for (auto it = data_set.begin() + 1; it != data_set.end(); ++it) {
insertNodeEnd(head, *it);
}
printNodes(head);
cout << " ----------------------------------- " << endl;
auto iter = insertNodeEnd(head, "Utopic");
printNodes(head);
cout << " ----------------------------------- " << endl;
insertNodeAfter(iter, "Xenial");
printNodes(head);
freeNodes(head);
return EXIT_SUCCESS;
}
출력:
node 0 - data: Precise
node 1 - data: Quantal
node 2 - data: Saucy
node 3 - data: Raring
-----------------------------------
node 0 - data: Precise
node 1 - data: Quantal
node 2 - data: Saucy
node 3 - data: Raring
node 4 - data: Utopic
-----------------------------------
node 0 - data: Precise
node 1 - data: Quantal
node 2 - data: Saucy
node 3 - data: Raring
node 4 - data: Utopic
node 5 - data: Xenial
연결된 목록의 시작 부분에 노드를 삽입하는 함수 구현
단일 연결 목록에 대한 또 다른 유용한 삽입 작업은 처음에 새 노드를 추가하는 것입니다. 이 함수는 목록 자체에 액세스하기 위해 항상 목록의 헤드가 저장되므로 가장 좋은 실행 시간O(1)
를 갖습니다. insertNodeFront
함수는 루트 포인터와 노드에 저장해야하는string
객체에 대한 참조를 가져옵니다. 이 프로세스는 새로운 연결 목록과 전면 삽입을 초기화하는 데 사용할 수 있도록 구현됩니다.
또는root
인수가nullptr
가 아닌 경우 새 노드를 할당하도록 함수를 다시 작성할 수 있습니다. 그렇지 않으면nullptr
를 반환하여 함수가 실패했음을 나타냅니다. 이러한 함수의 인터페이스는 프로그래머의 요구와ListNode
의 구조에 따라 다릅니다.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
struct ListNode {
struct ListNode *next{};
string data;
};
struct ListNode *insertNodeEnd(struct ListNode *root, string data) {
auto new_node = new ListNode;
if (root) {
while (root->next) root = root->next;
new_node->next = nullptr;
new_node->data = std::move(data);
root->next = new_node;
return root->next;
}
new_node->next = nullptr;
new_node->data = std::move(data);
return new_node;
}
struct ListNode *insertNodeFront(struct ListNode *&root, string data) {
auto new_node = new ListNode;
if (root) {
new_node->next = root;
new_node->data = std::move(data);
root = new_node;
return root;
}
new_node->next = nullptr;
new_node->data = std::move(data);
return new_node;
}
void freeNodes(struct ListNode *root) {
struct ListNode *tmp = nullptr;
while (root) {
tmp = root;
root = root->next;
delete tmp;
}
}
void printNodes(struct ListNode *node) {
auto count = 0;
while (node) {
cout << "node " << count << " - data: " << node->data << endl;
node = node->next;
count++;
}
}
int main() {
struct ListNode *head = nullptr;
vector<string> data_set = {"Precise", "Quantal", "Saucy", "Raring"};
head = insertNodeEnd(head, data_set.at(0));
for (auto it = data_set.begin() + 1; it != data_set.end(); ++it) {
insertNodeEnd(head, *it);
}
printNodes(head);
cout << " ----------------------------------- " << endl;
insertNodeFront(head, "Bionic");
printNodes(head);
freeNodes(head);
return EXIT_SUCCESS;
}
출력:
node 0 - data: Precise
node 1 - data: Quantal
node 2 - data: Saucy
node 3 - data: Raring
-----------------------------------
node 0 - data: Bionic
node 1 - data: Precise
node 2 - data: Quantal
node 3 - data: Saucy
node 4 - data: Raring
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook