数据结构学习(一)

数据结构之深度优先遍历java实现 

数据结构是码农的基本功,基础不牢,地动山摇,为了防止自己忘记,特立一个专题专门学习数据结构;今天学习的是数据结构中的深度优先遍历的java实现方法,本身是一个技术菜,遇到很多问题,希望慢慢克服以后。深度优先实际上需要用到栈来实现,这里,用的是二维邻接矩阵来表示节点和节点之间的关系,具体的基础知识就不细说了,大家都是大神,举一个例子说明步骤就好啦!! 


讲解:选取一个顶点一路往下走,并且访问过的节点放入栈之中,一直到没有下一个可以访问的节点为止,之后按照栈”先进后出”的原则,一个一个往回找节点,若有可以继续访问的节点就继续放入栈中,没有的话就直接栈中弹出元素,继续查找;一直到栈中没有元素的时候就算访问结束了!!针对这个例子来讲,

  1. 从节点A开始进行,一路往左走,从而有A->B->C->D->E->F->G->H;此时栈中的元素也是:A->B->C->D->E->F->G->H;
  2. 访问完H之后发现与H邻接的节点都已经被访问过了,所以此时栈就起作用了,此时栈顶元素H弹出,栈顶元素变成G,G的邻接的顶点也已经都被访问过了,继续弹出……….过了N久,到栈中栈顶为D的时候,发现I未被访问,所以将I压入栈中,此时栈中元素为:A->B->C->D->I;再按照步骤进行; 
  3. 栈中元素为空了,深度搜索结束,所以一种输出顺序为: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>



到这里,深遍历基础部分全部结束了,难的我也不会,哈哈,这里的例子是大话数据结构中的,这本书还不错哈!!!继续加油!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值