1.深さ優先探索
グラフの深度優先トラバーサルの方法は、グラフの頂点vから開始することです。
(1)頂点vにアクセスし、
(2)vの未アクセスの隣接ポイントから順番に開始し、深度優先トラバーサルを実行します。グラフ;グラフとvまで同じパスの頂点が訪問される;
(3)現時点で訪問されていない頂点がグラフにまだある場合は、訪問されていない頂点から開始し、深さを再実行します-グラフ内のすべての頂点にアクセスするまでの最初のトラバーサル。
最初に二分木を見てください:
この二分木の場合、深さ優先探索は事前注文トラバーサルです。トラバーサルの結果は次のとおりです。12 4 8 5 3 6 7
この二分木でDFS検索を実行するときは、最初にそのような二分木を作成しましょう。
package test;
public class DFSBinaryTree {
public static void main(String[] args) {
//创建节点
Node root=new Node(1);
Node node2=new Node(2);
Node node3=new Node(3);
Node node4=new Node(4);
Node node5=new Node(5);
Node node6=new Node(6);
Node node7=new Node(7);
Node node8=new Node(8);
//连接节点
root.left=node2;
root.right=node3;
node2.left=node4;
node2.right=node5;
node3.left=node6;
node3.right=node7;
node4.left=node8;
}
}
class Node{
Node left;
Node right;
int val;
public Node(int val)
{
this.val=val;
}
}
- DFSの再帰形式
void DFS(Node root)
{
if(root==null)
return;
System.out.print(root.val+" ");
DFS(root.left);
DFS(root.right);
}
main関数で呼び出されます:
DFSBinaryTree t=new DFSBinaryTree();
t.DFS(root);
完全なコード:
package test;
public class DFSBinaryTree {
public static void main(String[] args) {
//创建节点
Node root=new Node(1);
Node node2=new Node(2);
Node node3=new Node(3);
Node node4=new Node(4);
Node node5=new Node(5);
Node node6=new Node(6);
Node node7=new Node(7);
Node node8=new Node(8);
//连接节点
root.left=node2;
root.right=node3;
node2.left=node4;
node2.right=node5;
node3.left=node6;
node3.right=node7;
node4.left=node8;
DFSBinaryTree t=new DFSBinaryTree();
t.DFS(root);
}
void DFS(Node root)
{
if(root==null)
return;
System.out.print(root.val+" ");
DFS(root.left);
DFS(root.right);
}
}
class Node{
Node left;
Node right;
int val;
public Node(int val)
{
this.val=val;
}
}
出力結果は、前に作成した事前注文トラバーサル結果と同じであることがわかります。
- DFSの非再帰形式
非再帰形式のDFSはスタックを使用します。初めて、ルートノードがスタックにプッシュされ、次に右の子ノード(右の子ノード)がプッシュされ、次に左の子ノードが再度プッシュされます。 、次にスタックが継続的にプッシュされ、スタックにアクセスします。
void DFSNotRecursive(Node root)
{
Stack<Node> st=new Stack<>();
st.push(root);
while(!st.isEmpty())
{
Node top=st.pop();//获取栈顶节点
System.out.print(top.val+" ");
if(top.right!=null)//先压右子节点
st.push(top.right);
if(top.left!=null)
st.push(top.left);
}
}
結果は、DFSの再帰形式と一致しています
2.幅優先探索
幅優先探索は通常、非再帰形式のキューを採用します。バイナリツリーの場合、幅優先探索はレイヤーシーケンストラバーサルを実現できます。この記事のバイナリツリーを例にとると、レイヤーシーケンストラバーサルの結果は次のようになります。 2 3 4 5 6 7 8
void BFS(Node root)
{
Queue<Node> q=new LinkedList<>();
q.offer(root);//将节点添加到队尾
while(!q.isEmpty())
{
Node cur=q.poll();//获取队首节点并将其移除队列
System.out.print(cur.val+" ");
if(cur.left!=null)
q.offer(cur.left);
if(cur.right!=null)
q.offer(cur.right);
}
}
フルテキストコード:
package test;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class DFSBinaryTree {
public static void main(String[] args) {
//创建节点
Node root=new Node(1);
Node node2=new Node(2);
Node node3=new Node(3);
Node node4=new Node(4);
Node node5=new Node(5);
Node node6=new Node(6);
Node node7=new Node(7);
Node node8=new Node(8);
//连接节点
root.left=node2;
root.right=node3;
node2.left=node4;
node2.right=node5;
node3.left=node6;
node3.right=node7;
node4.left=node8;
DFSBinaryTree t=new DFSBinaryTree();
t.DFS(root);
System.out.println();
t.DFSNotRecursive(root);
System.out.println();
t.BFS(root);
}
void DFS(Node root)
{
if(root==null)
return;
System.out.print(root.val+" ");
DFS(root.left);
DFS(root.right);
}
void DFSNotRecursive(Node root)
{
Stack<Node> st=new Stack<>();
st.push(root);
while(!st.isEmpty())
{
Node top=st.pop();//获取栈顶节点
System.out.print(top.val+" ");
if(top.right!=null)//先压右子节点
st.push(top.right);
if(top.left!=null)
st.push(top.left);
}
}
void BFS(Node root)
{
Queue<Node> q=new LinkedList<>();
q.offer(root);//将节点添加到队尾
while(!q.isEmpty())
{
Node cur=q.poll();//获取队首节点并将其移除队列
System.out.print(cur.val+" ");
if(cur.left!=null)
q.offer(cur.left);
if(cur.right!=null)
q.offer(cur.right);
}
}
}
class Node{
Node left;
Node right;
int val;
public Node(int val)
{
this.val=val;
}
}