「≪データ構造|Data Structure|Essbase_Studio≫」接続リスト(リンク・リスト)
すべての内容は以下の内容を参照して作成されています.
1.定義と性質
1.定義と性質
定義#テイギ#
エレメントを格納するときに、次のエレメントが存在する場所を含むように格納されるデータ構造.
気性
✔k個目の要素をチェック/変更する👉🏻 O(k)
たとえば、3->13->72->5を格納する接続リストがあります.ここで3番目の要素72を見つけるには、3〜13、13〜72を経なければならない.このように行かなければ、72がどこにあるか分からない.配列とは異なり、要素の空間内の位置は連続的ではありません.
要素の追加/削除👉🏻 O(1)
АААААААААААААА
種類
✔勘定科目単点接続リスト
各要素に次の要素のアドレスがある接続リスト.
✔勘定科目の二重接続リスト
各要素には、前の要素と次の要素のアドレスがあります.
しかし、欠点は、要素が持つべき情報を追加したため、より多くのメモリが消費されることです.
(STLにはlistという名前の接続リストがあり、二重接続リストとして構成されていることに注意してください.)
勘定科目の勘定科目のプロトタイプ接続のリスト
端点は最初の端点に関連付けられます.図の例は接続リストとして表示されますが、各要素には前の要素と次の要素のアドレスがあります.
アレイvs接続リスト
✔朕k次元素の接近
배열
はO(1)であり、연결 리스트
はO(k)である.
АААААААААААА
배열
はO(N)であり、연결 리스트
はO(1)である.
ただし、厳密には、接続リストにも3番目の要素の後に20という要素を追加したい場合は、まず3番目の要素を見つけてからO(1)に追加する必要があります.状況は少し異なります.これは実装セクションで詳しく説明します.
勘定科目の処理
배열
は連続的であり、연결 리스트
は不連続である.
✔▼余分なスペース(オーバーヘッド)
배열
は、追加のスペースを必要とせずに、データを簡単に格納するだけです.計算をしなければならない場合は、intで長さ情報を格納する必要がありますが、これは小さすぎて、心配する必要はありません.
ただし、연결 리스트
において、各要素は、以下の要素のアドレス値を有しなければならない.したがって、32ビットコンピュータの場合、アドレス値は32ビット(=4バイト)単位であるため、追加の4 Nバイトが必要であり、64ビットコンピュータの場合、追加の8 Nバイトが必要である.これは、Nに比例した追加メモリを使用することを意味します.
2.機能と実施
機能
✔朕は任意の位置の要素を検査/変更する👉🏻 O(N)
次に説明するように、配列とは異なる任意の位置の要素に到達するには、最初の位置から開始し、その位置に到達するまで順次アクセスする必要があります.
これは接続リストの構造上は仕方がありません.明らかにすべての要素がメモリのどこかにありますが、最初の要素のアドレスしか知りません.
したがって、k番目の要素を見るにはO(k)の時間が必要であり、要素全体がN個ある場合、平均してN/2の時間が必要であるため、O(N)とみなすことができる.
✔朕は任意の場所で元素を追加/削除する👉🏻 O(1)
追加
たとえば、a->cとaの後ろにbを追加する場合は、後ろのすべての要素を配列のように移動する必要はありません.aとbで次の要素のアドレスを変更するだけです.
(ただし、追加したいアドレスを知っている場合にのみO(1)となる点は間違いありません.コマンドがaアドレスではなくbという要素を3番目の要素の後に追加する場合、3番目の要素を見つけるには追加の時間がかかるため、O(1)とは言えません.
削除
たとえば、a->b->cでbを削除したい場合は、aの次のアドレスをcに変更してbのメモリを解放するだけです.
インプリメンテーション
#include <bits/stdc++.h>
using namespace std;
const int MX = 1000005;
int dat[MX], pre[MX], nxt[MX];
int unused = 1;
void insert(int addr, int num){
dat[unused] = num;
pre[unused] = addr;
nxt[unused] = nxt[addr];
if(nxt[addr] != -1) pre[nxt[addr]] = unused;
nxt[addr] = unused;
unused++;
}
void erase(int addr){
nxt[pre[addr]] = nxt[addr];
if(nxt[addr] != -1) pre[nxt[addr]] = pre[addr];
}
void traverse(){
int cur = nxt[0];
while(cur != -1){
cout << dat[cur] << ' ';
cur = nxt[cur];
}
cout << "\n\n";
}
void insert_test(){
cout << "****** insert_test *****\n";
insert(0, 10); // 10(address=1)
traverse();
insert(0, 30); // 30(address=2) 10
traverse();
insert(2, 40); // 30 40(address=3) 10
traverse();
insert(1, 20); // 30 40 10 20(address=4)
traverse();
insert(4, 70); // 30 40 10 20 70(address=5)
traverse();
}
void erase_test(){
cout << "****** erase_test *****\n";
erase(1); // 30 40 20 70
traverse();
erase(2); // 40 20 70
traverse();
erase(4); // 40 70
traverse();
erase(5); // 40
traverse();
}
int main(void) {
fill(pre, pre+MX, -1);
fill(nxt, nxt+MX, -1);
insert_test();
erase_test();
}
3. STL list
push_back, pop_back, push_front, pop_front 👉🏻 O(1)
iterator 👉🏻 アドレスロール#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> L = {1,2};
list<int>::iterator t = L.begin(); //t는 1을 가리키는중
//c++11이상이면 auto t = L.begin(); 도 가능
L.push_front(10); // 10,1,2
cout << *t << '\n'; // 1
L.push_back(5); //10,1,2,5
L.insert(t, 6); //t가 가리키는 곳 앞에 삽입, 10,6,1,2,5
t++; //t를 1칸 앞으로, t가 가리키는 값은 2
t = L.erase(t); //t가 가리키는 값 제거, 그다움 원소 5 위치 반환
cout << *t << '\n'; //5
for(auto i: L) cout << i << ' '; //10,6,1,5
cout << '\n';
for(list<int>::iterator it=L.begin(); it != L.end(); it++)
cout << *it << ' '; //10,6,1,5
}
4.練習問題
✔️ BOJ 1406号:編集 #include <iostream>
#include <list>
using namespace std;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
string s;
list<char> L;
int M;
cin >> s >> M;
for(auto e: s) L.push_back(e);
auto cursor = L.end();
char cmd;
for(int i = 0; i < M; i++) {
cin >> cmd;
switch (cmd)
{
case 'L':
if(cursor != L.begin())
cursor--;
break;
case 'D':
if(cursor != L.end())
cursor++;
break;
case 'B':
if(cursor != L.begin()) {
cursor--;
cursor = L.erase(cursor);
}
break;
default:
char ch;
cin >> ch;
L.insert(cursor, ch);
break;
}
}
for(auto e: L) cout << e;
}
Reference
この問題について(「≪データ構造|Data Structure|Essbase_Studio≫」接続リスト(リンク・リスト)), 我々は、より多くの情報をここで見つけました
https://velog.io/@thing-zoo/자료구조연결리스트Linked-List
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
機能
✔朕は任意の位置の要素を検査/変更する👉🏻 O(N)
次に説明するように、配列とは異なる任意の位置の要素に到達するには、最初の位置から開始し、その位置に到達するまで順次アクセスする必要があります.
これは接続リストの構造上は仕方がありません.明らかにすべての要素がメモリのどこかにありますが、最初の要素のアドレスしか知りません.
したがって、k番目の要素を見るにはO(k)の時間が必要であり、要素全体がN個ある場合、平均してN/2の時間が必要であるため、O(N)とみなすことができる.
✔朕は任意の場所で元素を追加/削除する👉🏻 O(1)
追加
たとえば、a->cとaの後ろにbを追加する場合は、後ろのすべての要素を配列のように移動する必要はありません.aとbで次の要素のアドレスを変更するだけです.
(ただし、追加したいアドレスを知っている場合にのみO(1)となる点は間違いありません.コマンドがaアドレスではなくbという要素を3番目の要素の後に追加する場合、3番目の要素を見つけるには追加の時間がかかるため、O(1)とは言えません.
削除
たとえば、a->b->cでbを削除したい場合は、aの次のアドレスをcに変更してbのメモリを解放するだけです.
インプリメンテーション
#include <bits/stdc++.h>
using namespace std;
const int MX = 1000005;
int dat[MX], pre[MX], nxt[MX];
int unused = 1;
void insert(int addr, int num){
dat[unused] = num;
pre[unused] = addr;
nxt[unused] = nxt[addr];
if(nxt[addr] != -1) pre[nxt[addr]] = unused;
nxt[addr] = unused;
unused++;
}
void erase(int addr){
nxt[pre[addr]] = nxt[addr];
if(nxt[addr] != -1) pre[nxt[addr]] = pre[addr];
}
void traverse(){
int cur = nxt[0];
while(cur != -1){
cout << dat[cur] << ' ';
cur = nxt[cur];
}
cout << "\n\n";
}
void insert_test(){
cout << "****** insert_test *****\n";
insert(0, 10); // 10(address=1)
traverse();
insert(0, 30); // 30(address=2) 10
traverse();
insert(2, 40); // 30 40(address=3) 10
traverse();
insert(1, 20); // 30 40 10 20(address=4)
traverse();
insert(4, 70); // 30 40 10 20 70(address=5)
traverse();
}
void erase_test(){
cout << "****** erase_test *****\n";
erase(1); // 30 40 20 70
traverse();
erase(2); // 40 20 70
traverse();
erase(4); // 40 70
traverse();
erase(5); // 40
traverse();
}
int main(void) {
fill(pre, pre+MX, -1);
fill(nxt, nxt+MX, -1);
insert_test();
erase_test();
}
3. STL list
push_back, pop_back, push_front, pop_front 👉🏻 O(1)
iterator 👉🏻 アドレスロール#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> L = {1,2};
list<int>::iterator t = L.begin(); //t는 1을 가리키는중
//c++11이상이면 auto t = L.begin(); 도 가능
L.push_front(10); // 10,1,2
cout << *t << '\n'; // 1
L.push_back(5); //10,1,2,5
L.insert(t, 6); //t가 가리키는 곳 앞에 삽입, 10,6,1,2,5
t++; //t를 1칸 앞으로, t가 가리키는 값은 2
t = L.erase(t); //t가 가리키는 값 제거, 그다움 원소 5 위치 반환
cout << *t << '\n'; //5
for(auto i: L) cout << i << ' '; //10,6,1,5
cout << '\n';
for(list<int>::iterator it=L.begin(); it != L.end(); it++)
cout << *it << ' '; //10,6,1,5
}
4.練習問題
✔️ BOJ 1406号:編集 #include <iostream>
#include <list>
using namespace std;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
string s;
list<char> L;
int M;
cin >> s >> M;
for(auto e: s) L.push_back(e);
auto cursor = L.end();
char cmd;
for(int i = 0; i < M; i++) {
cin >> cmd;
switch (cmd)
{
case 'L':
if(cursor != L.begin())
cursor--;
break;
case 'D':
if(cursor != L.end())
cursor++;
break;
case 'B':
if(cursor != L.begin()) {
cursor--;
cursor = L.erase(cursor);
}
break;
default:
char ch;
cin >> ch;
L.insert(cursor, ch);
break;
}
}
for(auto e: L) cout << e;
}
Reference
この問題について(「≪データ構造|Data Structure|Essbase_Studio≫」接続リスト(リンク・リスト)), 我々は、より多くの情報をここで見つけました
https://velog.io/@thing-zoo/자료구조연결리스트Linked-List
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> L = {1,2};
list<int>::iterator t = L.begin(); //t는 1을 가리키는중
//c++11이상이면 auto t = L.begin(); 도 가능
L.push_front(10); // 10,1,2
cout << *t << '\n'; // 1
L.push_back(5); //10,1,2,5
L.insert(t, 6); //t가 가리키는 곳 앞에 삽입, 10,6,1,2,5
t++; //t를 1칸 앞으로, t가 가리키는 값은 2
t = L.erase(t); //t가 가리키는 값 제거, 그다움 원소 5 위치 반환
cout << *t << '\n'; //5
for(auto i: L) cout << i << ' '; //10,6,1,5
cout << '\n';
for(list<int>::iterator it=L.begin(); it != L.end(); it++)
cout << *it << ' '; //10,6,1,5
}
✔️ BOJ 1406号:編集
#include <iostream>
#include <list>
using namespace std;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
string s;
list<char> L;
int M;
cin >> s >> M;
for(auto e: s) L.push_back(e);
auto cursor = L.end();
char cmd;
for(int i = 0; i < M; i++) {
cin >> cmd;
switch (cmd)
{
case 'L':
if(cursor != L.begin())
cursor--;
break;
case 'D':
if(cursor != L.end())
cursor++;
break;
case 'B':
if(cursor != L.begin()) {
cursor--;
cursor = L.erase(cursor);
}
break;
default:
char ch;
cin >> ch;
L.insert(cursor, ch);
break;
}
}
for(auto e: L) cout << e;
}
Reference
この問題について(「≪データ構造|Data Structure|Essbase_Studio≫」接続リスト(リンク・リスト)), 我々は、より多くの情報をここで見つけました https://velog.io/@thing-zoo/자료구조연결리스트Linked-Listテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol