深度搜索和广度搜索领接表实现_Java数据结构——图的深度和广度优先遍历(递归和非递归都有,邻接表和邻接矩阵)...

本文介绍了如何使用Java实现图的创建和遍历,包括邻接矩阵和邻接表的创建,以及两种遍历方式:深度优先遍历(递归和非递归)和广度优先遍历。详细代码展示了邻接表和邻接矩阵的遍历过程,包括图的节点和边的管理,以及搜索算法的实现。
摘要由CSDN通过智能技术生成

图论是一个很重要的工具,这节主要是图的创建和遍历的Java代码,不讲理论,只撸代码,理论网上很多,具体一步步该怎么走,其他的贴子也都给全了,但是都是c语言,我们用Java实现和模拟图论。

内容有点多,给个目录:

目录:

1. 图结点的创建

2. 图的创建

2.1 图的结构和初始化

2.2 邻接矩阵

2.3 邻接表

3. 邻接表的两种遍历

3.1 深度优先遍历(邻接表)

3.1.1 递归算法(邻接表)

3.1.2 非递归算法(邻接表)

3.2 广度优先遍历(邻接表)

4. 邻接矩阵的两种遍历

4.1 深度优先遍历(邻接矩阵)

4.1.1 递归算法(邻接矩阵)

4.1.2 非递归算法(邻接矩阵)

4.2 广度优先搜索(邻接矩阵)

5. 项目完整代码

1. 图结点的创建

public class Node {

public int name;

public Node next;

public Boolean flag;

public Node() {

// TODO Auto-generated constructor stubthis.name = 0;

this.next = null;

this.flag = false;

}

public Node(int name) {

this.name = name;

this.next = null;

this.flag = false;

}

}

2. 图的创建

2.1 图的结构和初始化

import java.util.Scanner;

public class Graph {

public Node[] nodes;

public int[][] A;

public int Sidenum;

public Seqqueue queue;

public Seqstack stack;

Scanner scanner;

public Graph(int Nodenum, int Sidenum) {

this.nodes = new Node[Nodenum];

for (int i = 0; i < Nodenum; i++) {

this.nodes[i] = new Node(i);

}

this.A = new int[Nodenum][Nodenum];

this.Sidenum = Sidenum;

for (int i = 0; i < Nodenum; i++) {

for (int j = 0; j < Nodenum; j++) {

this.A[i][j] = 0;

}

}

scanner = new Scanner(System.in);

this.queue = new Seqqueue();

this.queue.initQueue(20);

this.stack = new Seqstack();

this.stack.InitStack(20);

}

}

2.2 邻接矩阵

// 邻接矩阵创建(有向图)void creat1() {

int a, b;

for (int i = 0; i < this.Sidenum; i++) {

a = scanner.nextInt();

b = scanner.nextInt();

this.A[a][b] = 1;

}

System.out.println("图创建成功");

}

// 邻接矩阵创建(无向图)void creat2() {

int a, b;

for (int i = 0; i < this.Sidenum; i++) {

a = scanner.nextInt();

b = scanner.nextInt();

this.A[a][b] = 1;

this.A[b][a] = 1;

}

System.out.println("图创建成功");

}

// 遍历输出邻接矩阵void traver1() {

for (int i = 0; i < nodes.length; i++) {

for (int j = 0; j < nodes.length; j++) {

System.out.print(this.A[i][j] + " ");

}

System.out.println("");

}

}

2.3 邻接表

// 邻接表创建void creat3() {

int a, b;

for (int i = 0; i < this.Sidenum; i++) {

a = scanner.nextInt();

b = scanner.nextInt();

Node node = this.nodes[a];

// 防止把同一条边加入多次while (node.next != null && node.next.name != b) {

node = node.next;

}

if (node.next == null) {

Node n = new Node(b);

n.next = nodes[a].next;

nodes[a].next = n;

}

}

System.out.println("图创建成功");

}

// 遍历输出邻接表void traver2() {

Node node;

for (int i = 0; i < nodes.length; i++) {

node = nodes[i];

System.out.print(node.name + ":");

while (node.next != null) {

System.out.print(node.next.name + " ");

node = node.next;

}

System.out.println("");

}

}

3. 邻接表的两种遍历

flag属性用来标记结点有没有被访问过,所以需要初始化。

// 初始化访问标记void initFlag() {

// 初始化for (int i = 0; i < this.nodes.length; i++) {

this.nodes[i].flag = false;

}

}

3.1 深度优先遍历(邻接表)

3.1.1 递归算法(邻接表)

// 深度优先遍历(从head结点开始) 递归算法 邻接表void DFS1(Node head) {

Node pNode;

if (!this.nodes[head.name].flag) {

System.out.print(head.name + " ");

this.nodes[head.name].flag = true;

}

pNode = this.nodes[head.name].next;

while (pNode != null) {

if (!this.nodes[pNode.name].flag) {

DFS1(pNode);

} else {

pNode = pNode.next;

}

}

}

3.1.2 非递归算法(邻接表)

用到的栈,定义在文章最后完整项目代码中有,这块只是引用。

// 深度优先遍历(从head结点开始) 非递归算法 邻接表void DFS2(Node head) {

// 初始化访问标记initFlag();

// 初始化栈this.stack.InitStack(20);

Node pNode, wNode;

this.stack.push(head);

System.out.print(head.name + " ");

this.nodes[head.name].flag = true;

while (!this.stack.IsEmpty()) {

pNode = this.stack.pop();

wNode = pNode.next;

while (wNode != null) {

if (!this.nodes[wNode.name].flag) {

this.stack.push(wNode);

this.nodes[wNode.name].flag = true;

System.out.print(wNode.name + " ");

wNode = this.nodes[wNode.name].next;

} else {

wNode = wNode.next;

}

}

}

}

3.2 广度优先遍历(邻接表)

因为广度优先遍历需要用到队列,所以不能递归,递归只能是用到栈时才能。

用到的队列,定义在文章最后完整项目代码中有,这块只是引用。

void BFS1(Node head) {

// 初始化访问标记initFlag();

// 初始化队列this.queue.initQueue(20);

Node pNode;

this.queue.enterQueue(head);

this.nodes[head.name].flag = true;

while (!this.queue.isEmpty()) {

pNode = this.queue.deleteQueue();

pNode = this.nodes[pNode.name];

System.out.print(pNode.name + " ");

while (pNode != null) {

pNode = pNode.next;

if (pNode != null && !this.nodes[pNode.name].flag) {

this.queue.enterQueue(pNode);

this.nodes[pNode.name].flag = true;

}

}

}

}

4. 邻接矩阵的两种遍历

4.1 深度优先遍历(邻接矩阵)

4.1.1 递归算法(邻接矩阵)

// 深度优先遍历(从0号结点开始) 递归算法 邻接矩阵void DFSM(int i) {

int j = 0;

System.out.print(this.nodes[i].name + " ");

this.nodes[i].flag = true;

for (j = 0; j < this.Sidenum; j++) {

if (this.A[i][j] == 1 && !this.nodes[j].flag) {

DFSM(j);

}

}

}

void DFS3() {

for (int i = 0; i < this.Sidenum; i++) {

if (!this.nodes[i].flag) {

DFSM(i);

}

}

}

4.1.2 非递归算法(邻接矩阵)

用到的栈,定义在文章最后完整项目代码中有,这块只是引用。

// 深度优先遍历(从0号结点开始) 非递归算法 邻接矩阵void DFS4(Node head) {

// 初始化访问标记initFlag();

int i = 0;

// 初始化栈this.stack.InitStack(20);

Node pNode, wNode = null;

this.stack.push(head);

System.out.print(head.name + " ");

this.nodes[head.name].flag = true;

while (!this.stack.IsEmpty()) {

pNode = this.stack.getTop();

for (i = 0; i < this.Sidenum; i++) {

if (this.A[pNode.name][i] == 1 && !this.nodes[i].flag) {

System.out.print(this.nodes[i].name + " ");

this.nodes[i].flag = true;

this.stack.push(this.nodes[i]);

break;

}

}

if (i == this.Sidenum) {

this.stack.pop();

}

}

}

4.2 广度优先搜索(邻接矩阵)

因为广度优先遍历需要用到队列,所以不能递归,递归只能是用到栈时才能。

用到的队列,定义在文章最后完整项目代码中有,这块只是引用。

// 广度优先遍历(从0号结点开始) 非递归算法 邻接矩阵void BFS2(int k) {

// 初始化被访问标记initFlag();

// 初始化队列this.queue.initQueue(20);

Node node;

System.out.print(this.nodes[k].name + " ");

this.nodes[k].flag = true;

this.queue.enterQueue(this.nodes[k]);

while (!this.queue.isEmpty()) {

node = this.queue.deleteQueue();

for (int i = 0; i < this.Sidenum; i++) {

if (this.A[node.name][i] == 1 && !this.nodes[i].flag) {

System.out.print(this.nodes[i].name + " ");

this.nodes[i].flag = true;

this.queue.enterQueue(this.nodes[i]);

}

}

}

}

5. 项目完整代码

项目的代码比较多,主要有下面几个类,防止查找麻烦,目录如下:

目录:class Node 结点定义

class Seqqueue 队列定义

class Seqstack 栈的定义

class Graph 图的定义及操作

class Client 测试类

内容://class Node 结点定义

package com.company.project.graph;

public class Node {

public int name;

public Node next;

public Boolean flag;

public Node() {

// TODO Auto-generated constructor stubthis.name = 0;

this.next = null;

this.flag = false;

}

public Node(int name) {

this.name = name;

this.next = null;

this.flag = false;

}

}

2. //class Seqqueue 队列定义

package com.company.project.graph;

public class Seqqueue {

public Node[] queue;

public int QUEUE_SIZE;

public int front;

public int rear;

//初始化队列public void initQueue(int size) {

this.QUEUE_SIZE = size;

this.queue = new Node[size];

this.front = 0;

this.rear = 0;

}

//判断队列是否为空public boolean isEmpty() {

if(this.front == this.rear ) {

return true;

}

else {

return false;

}

}

//判断队列是否为满public boolean isFull() {

if((this.front % this.QUEUE_SIZE) == ((this.rear+1) % this.QUEUE_SIZE)) {

return true;

}

else {

return false;

}

}

//入队public void enterQueue(Node node) {

if(isFull()) {

System.out.println("队列已经满了,入队失败");

return;

}

this.queue[this.rear] = node;

this.rear ++;

this.rear = this.rear % this.QUEUE_SIZE;

}

//出队public Node deleteQueue() {

if(isEmpty()){

System.out.println("队列为空,出队失败");

return null;

}

this.front = this.front % this.QUEUE_SIZE;

Node node = this.queue[this.front];

this.front++;

return node;

}

}

3. //class Seqstack 栈的定义

package com.company.project.graph;

public class Seqstack {

// 节点数组(模拟顺序栈)public Node[] nodes;

// 栈顶下标public int top;

public Seqstack() {

// TODO Auto-generated constructor stubthis.top = -1;

}

// 初始化栈public void InitStack(int size) {

this.nodes = new Node[size];

this.top = -1;

}

// 判断栈空public boolean IsEmpty() {

if (this.top == -1) {

return true;

}

return false;

}

// 判断栈满public boolean IsFull() {

if (this.top == this.nodes.length - 1) {

return true;

}

return false;

}

// 入栈public void push(Node node) {

if (IsFull()) {

System.out.println("栈已经满了,入栈失败");

return;

}

this.top++;

this.nodes[this.top] = node;

}

// 出栈public Node pop() {

if (IsEmpty()) {

System.out.println("栈已经空了,出栈失败");

return null;

}

Node node = this.nodes[this.top];

this.top--;

return node;

}

// 清空栈public void ClearStack() {

// 如果不为空,就一直出栈while (!IsEmpty()) {

Node node = pop();

}

}

// 拿到栈顶元素public Node getTop() {

if (IsEmpty()) {

System.out.println("栈中没有元素");

return null;

}

return this.nodes[this.top];

}

}

4. //class Graph 图的定义及操作

package com.company.project.graph;

import java.util.Scanner;

public class Graph {

public Node[] nodes;

public int[][] A;

public int Sidenum;

public Seqqueue queue;

public Seqstack stack;

Scanner scanner;

public Graph(int Nodenum, int Sidenum) {

this.nodes = new Node[Nodenum];

for (int i = 0; i < Nodenum; i++) {

this.nodes[i] = new Node(i);

}

this.A = new int[Nodenum][Nodenum];

this.Sidenum = Sidenum;

for (int i = 0; i < Nodenum; i++) {

for (int j = 0; j < Nodenum; j++) {

this.A[i][j] = 0;

}

}

scanner = new Scanner(System.in);

this.queue = new Seqqueue();

this.queue.initQueue(20);

this.stack = new Seqstack();

this.stack.InitStack(20);

}

// 邻接矩阵创建(有向图)void creat1() {

int a, b;

for (int i = 0; i < this.Sidenum; i++) {

a = scanner.nextInt();

b = scanner.nextInt();

this.A[a][b] = 1;

}

System.out.println("图创建成功");

}

// 邻接矩阵创建(无向图)void creat2() {

int a, b;

for (int i = 0; i < this.Sidenum; i++) {

a = scanner.nextInt();

b = scanner.nextInt();

this.A[a][b] = 1;

this.A[b][a] = 1;

}

System.out.println("图创建成功");

}

// 邻接表创建void creat3() {

int a, b;

for (int i = 0; i < this.Sidenum; i++) {

a = scanner.nextInt();

b = scanner.nextInt();

Node node = this.nodes[a];

// 防止把同一条边加入多次while (node.next != null && node.next.name != b) {

node = node.next;

}

if (node.next == null) {

Node n = new Node(b);

n.next = nodes[a].next;

nodes[a].next = n;

}

}

System.out.println("图创建成功");

}

// 遍历输出邻接矩阵void traver1() {

for (int i = 0; i < nodes.length; i++) {

for (int j = 0; j < nodes.length; j++) {

System.out.print(this.A[i][j] + " ");

}

System.out.println("");

}

}

// 遍历输出邻接表void traver2() {

Node node;

for (int i = 0; i < nodes.length; i++) {

node = nodes[i];

System.out.print(node.name + ":");

while (node.next != null) {

System.out.print(node.next.name + " ");

node = node.next;

}

System.out.println("");

}

}

//邻接表的两种遍历(递归和非递归)// 初始化访问标记void initFlag() {

// 初始化for (int i = 0; i < this.nodes.length; i++) {

this.nodes[i].flag = false;

}

}

// 深度优先遍历(从head结点开始) 递归算法 邻接表void DFS1(Node head) {

Node pNode;

if (!this.nodes[head.name].flag) {

System.out.print(head.name + " ");

this.nodes[head.name].flag = true;

}

pNode = this.nodes[head.name].next;

while (pNode != null) {

if (!this.nodes[pNode.name].flag) {

DFS1(pNode);

} else {

pNode = pNode.next;

}

}

}

// 深度优先遍历(从head结点开始) 非递归算法 邻接表void DFS2(Node head) {

// 初始化访问标记initFlag();

// 初始化栈this.stack.InitStack(20);

Node pNode, wNode;

this.stack.push(head);

System.out.print(head.name + " ");

this.nodes[head.name].flag = true;

while (!this.stack.IsEmpty()) {

pNode = this.stack.pop();

wNode = pNode.next;

while (wNode != null) {

if (!this.nodes[wNode.name].flag) {

this.stack.push(wNode);

this.nodes[wNode.name].flag = true;

System.out.print(wNode.name + " ");

wNode = this.nodes[wNode.name].next;

} else {

wNode = wNode.next;

}

}

}

}

// 广度优先遍历(从head结点开始)(非递归) 邻接表// 因为广度优先遍历需要用到队列,所以不能递归,递归只能是用到栈时才能void BFS1(Node head) {

// 初始化访问标记initFlag();

// 初始化队列this.queue.initQueue(20);

Node pNode;

this.queue.enterQueue(head);

this.nodes[head.name].flag = true;

while (!this.queue.isEmpty()) {

pNode = this.queue.deleteQueue();

pNode = this.nodes[pNode.name];

System.out.print(pNode.name + " ");

while (pNode != null) {

pNode = pNode.next;

if (pNode != null && !this.nodes[pNode.name].flag) {

this.queue.enterQueue(pNode);

this.nodes[pNode.name].flag = true;

}

}

}

}

//邻接矩阵的两种遍历(递归和非递归)邻接矩阵

// 深度优先遍历(从0号结点开始) 递归算法 邻接矩阵void DFSM(int i) {

int j = 0;

System.out.print(this.nodes[i].name + " ");

this.nodes[i].flag = true;

for (j = 0; j < this.Sidenum; j++) {

if (this.A[i][j] == 1 && !this.nodes[j].flag) {

DFSM(j);

}

}

}

void DFS3() {

for (int i = 0; i < this.Sidenum; i++) {

if (!this.nodes[i].flag) {

DFSM(i);

}

}

}

// 深度优先遍历(从0号结点开始) 非递归算法 邻接矩阵void DFS4(Node head) {

// 初始化访问标记initFlag();

int i = 0;

// 初始化栈this.stack.InitStack(20);

Node pNode, wNode = null;

this.stack.push(head);

System.out.print(head.name + " ");

this.nodes[head.name].flag = true;

while (!this.stack.IsEmpty()) {

pNode = this.stack.getTop();

for (i = 0; i < this.Sidenum; i++) {

if (this.A[pNode.name][i] == 1 && !this.nodes[i].flag) {

System.out.print(this.nodes[i].name + " ");

this.nodes[i].flag = true;

this.stack.push(this.nodes[i]);

break;

}

}

if (i == this.Sidenum) {

this.stack.pop();

}

}

}

// 广度优先遍历(从0号结点开始) 非递归算法 邻接矩阵void BFS2(int k) {

// 初始化被访问标记initFlag();

// 初始化队列this.queue.initQueue(20);

Node node;

System.out.print(this.nodes[k].name + " ");

this.nodes[k].flag = true;

this.queue.enterQueue(this.nodes[k]);

while (!this.queue.isEmpty()) {

node = this.queue.deleteQueue();

for (int i = 0; i < this.Sidenum; i++) {

if (this.A[node.name][i] == 1 && !this.nodes[i].flag) {

System.out.print(this.nodes[i].name + " ");

this.nodes[i].flag = true;

this.queue.enterQueue(this.nodes[i]);

}

}

}

}

}

5. //class Client 测试类(里面有邻接表和邻接矩阵 的全部操作测试,需要那个,把剩余的注释就行)

package com.company.project.graph;

import java.util.Scanner;

public class Client {

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

System.out.println("输入顶点数:");

int Nodenum = scanner.nextInt();

System.out.println("输入边数:");

int Sidenum = scanner.nextInt();

Graph graph = new Graph(Nodenum, Sidenum);

// 邻接矩阵创建// 邻接矩阵创建System.out.println("输入边的两个顶点:");

graph.creat1();

graph.traver1();

// 邻接表创建// 邻接表创建System.out.println("输入边的两个顶点:");

graph.creat3();

System.out.println("邻接表:");

graph.traver2();

//邻接表的搜索// 深度优先搜索System.out.println("深度优先搜索(递归)");

graph.initFlag();

graph.DFS1(graph.nodes[0]);

System.out.println("");

// 深度优先搜索System.out.println("深度优先搜索(非递归)");

graph.DFS2(graph.nodes[0]);

System.out.println("");

// 广度优先遍历System.out.println("广度优先搜索(非递归)");

graph.BFS1(graph.nodes[0]);

//邻接矩阵的搜索// 深度优先搜索System.out.println("深度优先搜索(递归)");

graph.initFlag();

graph.DFS3();

System.out.println("");

// 深度优先搜索System.out.println("深度优先搜索(非递归)");

graph.initFlag();

graph.DFS4(graph.nodes[0]);

System.out.println("");

// 广度优先搜索System.out.println("广度优先搜索(非递归)");

graph.initFlag();

graph.BFS2(0);

System.out.println("");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值