数据结构之深度优先遍历java实现
数据结构是码农的基本功,基础不牢,地动山摇,为了防止自己忘记,特立一个专题专门学习数据结构;今天学习的是数据结构中的深度优先遍历的java实现方法,本身是一个技术菜,遇到很多问题,希望慢慢克服以后。深度优先实际上需要用到栈来实现,这里,用的是二维邻接矩阵来表示节点和节点之间的关系,具体的基础知识就不细说了,大家都是大神,举一个例子说明步骤就好啦!!
讲解:选取一个顶点一路往下走,并且访问过的节点放入栈之中,一直到没有下一个可以访问的节点为止,之后按照栈”先进后出”的原则,一个一个往回找节点,若有可以继续访问的节点就继续放入栈中,没有的话就直接栈中弹出元素,继续查找;一直到栈中没有元素的时候就算访问结束了!!针对这个例子来讲,
- 从节点A开始进行,一路往左走,从而有A->B->C->D->E->F->G->H;此时栈中的元素也是:A->B->C->D->E->F->G->H;
- 访问完H之后发现与H邻接的节点都已经被访问过了,所以此时栈就起作用了,此时栈顶元素H弹出,栈顶元素变成G,G的邻接的顶点也已经都被访问过了,继续弹出……….过了N久,到栈中栈顶为D的时候,发现I未被访问,所以将I压入栈中,此时栈中元素为:A->B->C->D->I;再按照步骤进行;
- 栈中元素为空了,深度搜索结束,所以一种输出顺序为:A->B->C->D->E->F->G->H->I;
不多说了,代码贴上:
<span style="font-size:24px;"><span style="font-size:18px;">/**
* 棧類
*/
public class Stack
{
private int top;//棧頂指針
private int[] array;//數組表示
//构造函数初始化
public Stack(int maxSize)
{
top = -1;
array = new int[maxSize];
}
//删除栈顶元素
public int pop()
{
return array[top--];
}
// //插入一個元素(写的啥啊。。。)
// public int push(int in)
// {
// return array[++top];
// }
//插入一個元素
public void push(int in)
{
array[++top] = in;
}
//判斷是否為空
public boolean isEmpty()
{
return top == -1;
}
//查看當前栈顶元素大小值
public int peek()
{
return array[top];
}
}
/**
* 顶点类
*/
public class Vertex
{
public char label; //顶点的名称
public boolean isVisited;//顶点是否被访问过的标志位
//構造函數初始化參數
public Vertex(char label)
{
this.label = label;
isVisited = false;
}
}
/**
* 图类
*/
public class Graph
{
private final int MAX_VERTEX_NUMS = 20;//定义最大可以允许的顶点数目大小
private int currentVerts;//定义当前的顶点数目大小
private int[][] adjMat;//定义邻接矩阵
private Stack myStack;//定义图中即将使用的栈类(栈中存放的是顶点在顶点数组中的位置)
//注:还要增加一个存放所有顶点的顶点数组
private Vertex[] vertexs_array;
//构造函数进行初始化参数操作
public Graph()
{
currentVerts = 0;
adjMat = new int[MAX_VERTEX_NUMS][MAX_VERTEX_NUMS];
vertexs_array = new Vertex[MAX_VERTEX_NUMS];//初始化顶点数组
for (int i = 0; i < MAX_VERTEX_NUMS; i++)
{
for (int j = 0; j < MAX_VERTEX_NUMS; j++)
{
adjMat[i][j] = 0;//初始化邻接矩阵
}
}
myStack = new Stack(MAX_VERTEX_NUMS);
}
//向图中增加顶点的方法
public void addVertex(char lab)
{
vertexs_array[currentVerts++] = new Vertex(lab);
}
//向图中增加边的方法
public void addEdge(int start, int end)
{
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
//打印有向圖中頂點的方法
public void displayVertex(int index)
{
System.out.print(vertexs_array[index].label);
}
//寻找与顶点相邻接的所有未访问过的顶点的下标
public int getUnvisitedAdjVertex(int index)
{
for (int i = 0; i < MAX_VERTEX_NUMS; i++)
{
if(adjMat[index][i] == 1 && vertexs_array[i].isVisited == false)//与目标顶点邻接并且此顶点未被
{
vertexs_array[i].isVisited = true;//设置访问标志位true;
return i;
}
}
return -1;//若返回-1则表示没有找到满足条件的顶点
}
//深度优先搜索的核心算法实现
public void DFS()
{
Vertex startVertex = vertexs_array[0];//确定起始的顶点以便开始搜索
startVertex.isVisited = true;//标志访问位置为1
displayVertex(0);//先打印出来
//别忘了压栈处理
myStack.push(0);
while (!myStack.isEmpty())//只要栈不为空则循环执行
{
//错误
// int notVisitedAdjIndex = getUnvisitedAdjVertex(myStack.pop());//为何要pop?仅是查看。。
int notVisitedAdjIndex = getUnvisitedAdjVertex(myStack.peek());
if(notVisitedAdjIndex == -1)
{
// displayVertex(myStack.pop());//出栈并且打印(错误了)
//注意:是压栈的时候先进行输出打印的
myStack.pop();//仅执行出栈操作;
}
else
{
// myStack.push(notVisitedAdjIndex);//将值压进栈当中
//将值压进栈当中还要打印
displayVertex(notVisitedAdjIndex);
myStack.push(notVisitedAdjIndex);//将值压进栈当中
}
}
}
}
import org.junit.Test;
public class TestDfsMethod
{
@Test
public void test()
{
Graph graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addVertex('E');
graph.addEdge(0, 1);
graph.addEdge(0, 2);//AC边
graph.addEdge(0, 3);//AD边
graph.addEdge(1, 3);//BD边
System.out.print("Visits:");
graph.DFS();//深度优先搜索
System.out.println();
}
}</span></span>
到这里,深遍历基础部分全部结束了,难的我也不会,哈哈,这里的例子是大话数据结构中的,这本书还不错哈!!!继续加油!!