- ブロガーの紹介:勉強を頑張るための準備プログラム〜
- ブロガーのホームページ: @is Yaoyaozi
- 所属コラム: ジャワ島の冒険【リトルホワイトからビッグブラザーへの道】
序文
ヤオ・ヤオジは学校でブルーブリッジカップとACM選抜大会の準備をしており、最近アルゴリズムについて学んでいます。私はAcWing ウェブサイトの助けを借りて学びました. この記事は私の学習内容に関するメモです. 原則の説明のいくつかは、私の学習プロセス中に箇条書きの画面やコメントを見るかもしれない友人です. 私はそれがとても良いと思います.
この記事はデータ構造に関するもので、主に配列を使用してさまざまなデータ構造をシミュレートし、主にアルゴリズムの効率を向上させます。
比較的わかりにくい所やハゲているところは、絵を描いて理解するのに慣れているので、アルゴリズムのテンプレートやトピックに基づいて丁寧に描いた図をご覧いただけます.アルゴリズムを一緒に学んでいる学生の助けになれば幸いです!
やおやおじはまだ新人なので、よくわからないところや、よくわかるところがあるかもしれませんが、どんどん指摘してください!❤
知らせ!以下の各データ構造の説明方法は、コードテンプレート+テキスト記述&解説+図を採用
1.片方向リスト(隣接リスト)
機能: 主に隣接リスト、ストレージグラフ、およびツリーに使用されます。
コード テンプレート
// head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点,后一个
int head, e[N], ne[N], idx;
//NULL相当于-1,所以head = -1相当于head=NULL
// 初始化
void init()
{
head = -1;
idx = 0;
}
// 在链表头插入一个数a
void insert(int a)
{
e[idx] = a, ne[idx] = head, head = idx ++ ;
}
//将x插入到下标是k的点之后
void insert(int k, int x)
{
e[idx] = x;
ne[idx] = ne[k]
ne[k] = idx;
idx ++;
}
// 将头结点删除,需要保证头结点存在
void remove()
{
head = ne[head];
}
- ノードを格納するストレージ ノード配列
e[N]
と次のポインタ配列ne[N]
は、添字によって関連付けられます。 - idx は現在の操作の位置のみを記録し、一般的に実装されているリンク リスト idx は順不同です (フロント ノードとリア ノードの配列添字は連続している必要はなく、次の idx は現在の ne を通じて検出される必要があります) 。 [i]. これは 2 つの間の接続でもあります。
- head の先頭では
=-1
、この -1 は物理アドレスに相当しNULL
、リンクされたリストが空であること、つまり head が head ノードを指していることを示し、head補間法を使用してこの空のノードを巧みにテールノード。したがって、連想構造体によって実現される単方向リストの最後のノードのポインタ フィールドは でありNULL
、配列は単方向リストの最後のノードを実現しますne[i]=-1
。 - ここでシミュレートされているのは、ヘッド ノードがなく、ヘッド ポインターがヘッド ノードの単一リンク リストを直接指しているということです。
- 配列でシミュレートされた連結リストは、構造/クラスのシミュレーションではよくわかりませんが、本質は同じで、ノード Node と比較できます。
- というわけで、実際に絵を描くときは、それほど明確に分ける必要はありません. 実は、配列を使って連結リストをシミュレートする方法を学ぶ前は、配列と連結リストは物理的な構造に属していると思っていました.リンクされたリストが実際には論理構造であることを発見してください!
比較ポイント | 構造体/クラス モック ノード | アレイアナログノード |
---|---|---|
ノード自体のポインタ | 物理アドレス、ノード | 配列に添字を付けることにより、それ自体のポインターを表します |
数値フィールド | 構造体で定義するだけですnode.val |
val[ノード]、値フィールドを格納する配列を介して |
ポインター フィールド | 構造体で定義され、node. next |
next[ノード]、配列を介して格納 |
グラフィカル
挿入操作(ヘッド挿入方式)
2. 二重連結リスト
一重連結リストをシミュレートする配列について学んだ後、二重連結リストは実際には理解しやすいものです。実際には、もう 1 つのポインター フィールドがあります。
- 単方向リスト: ne[i] は、ポインターが i であるノードの次のポインターを格納します。
- 二重連結リスト
- l[i]、ポインタが i であるノードの先行ノード (前のノードを指す)
- r[i]、ポインターが i であるノードのバックドライバー (次のノードを指す)
//e[index],表示节点的值,l[index]表示节点的左指针,r[index]表示节点的右指针,idx表示当前用到哪个节点的”地址“
int e[N],l[N],r[N],idx;
//初始化
void init(){
//0是左端点,1是右端点
r[0] = 1,l[1] = 0;
idx = 2;
}
//在节点a的右边插入一个数x
void insert(int a,int x){
//1、让待插入节点占位
e[idx] = x;
//2、处理待插入点左右两侧
l[idx] = a,r[idx] = r[a];//注意,这里必须是r[a],因为a的下一个节点不一定和a顺序存储
//3、处理前一个节点和后一个节点
l[r[a]] = idx,r[a] = idx++;
}
Java Island Adventures [Little White から Boss への道]
LeetCode Daily Question – Attack on the Big Factory