日撸代码300行学习笔记 Day 36

1.邻接表

当我们存储图中的数据中时,如果顶点较多,而边数较少时,使用邻接矩阵来存储将极大的浪费空间,而为了解决这种浪费,提出了一种新的存储方式:邻接表。

顾名思义,这种存储方式是依据链式存储的方式从而实现的。将图中的顶点使用一个一维数组进行存储,表中各个节点由data域和next指针域组成,其中data是用来存储节点编号信息,next指向下一个邻接点。

2.代码

在之前的图的广度优先遍历中,使用的是for循环

而今天邻接表中将其for循环改成了while循环

具体代码如下:

	package graph;
	
	import tree.CircleObjectQueue;
	
	/**
	 *
	 * @author leeyz_1@163.com
	 */
	public class AdjacencyList {
	
		/**
		 * An inner class for adjacent node.
		 */
		class AdjacencyNode {
			/**
			 * The column index.
			 */
			int column;
	
			/**
			 * The next adjacent node.
			 */
			AdjacencyNode next;
	
			/**
			 *********************
			 * The first constructor.
			 * 
			 * @param paraColumn The column.
			 *********************
			 */
			public AdjacencyNode(int paraColumn) {
				column = paraColumn;
				next = null;
			}// Of AdjacencyNode
		}// Of class AdjacencyNode
	
		/**
		 * The number of nodes. This member variable may be redundant since it is always
		 * equal to headers.length.
		 */
		int numNodes;
	
		/**
		 * The headers for each row.
		 */
		AdjacencyNode[] headers;
	
		/**
		 *********************
		 * The first constructor.
		 * 
		 * @param paraMatrix The the matrix indicating the graph.
		 * 表示图形的矩阵
		 *********************
		 */
		public AdjacencyList(int[][] paraMatrix) {
			numNodes = paraMatrix.length;
	
			// Step 1. Initialize. The data in the headers are not meaningful.
			AdjacencyNode tempPreviousNode, tempNode;
	
			headers = new AdjacencyNode[numNodes];
			for (int i = 0; i < numNodes; i++) {
				headers[i] = new AdjacencyNode(-1);
				tempPreviousNode = headers[i];
				//找到权值不为0的点,此时找到的是邻接点
				for (int j = 0; j < numNodes; j++) {
					if (paraMatrix[i][j] == 0) {
						continue;
					} // Of if
	
					// Create a new node.
					tempNode = new AdjacencyNode(j);
	
					// Link.
					tempPreviousNode.next = tempNode;
					tempPreviousNode = tempNode;
				} // Of for j
			} // Of for i
		}// Of class AdjacentTable
	
		/**
		 *********************
		 * Overrides the method claimed in Object, the superclass of any class.
		 *********************
		 */
		public String toString() {
			String resultString = "";
	
			AdjacencyNode tempNode;
			for (int i = 0; i < numNodes; i++) {
				tempNode = headers[i].next;
	
				while (tempNode != null) {
					resultString += " (" + i + ", " + tempNode.column + ")";
					tempNode = tempNode.next;
				} // Of while
				resultString += "\r\n";
			} // Of for i
	
			return resultString;
		}// Of toString
	
		/**
		 * 
		 ***********************************
		 * @Title: breadthFirstTraversal   
		 * @Description:  
		 * @param: @param paraStartIndex  The start index
		 * @param: @return    The sequence of the visit.  
		 * @return: String       
		 ***********************************
		 */
		public String breadthFirstTraversal(int paraStartIndex) {
			CircleObjectQueue tempQueue = new CircleObjectQueue();
			String resultString = "";
	
			boolean[] tempVisitedArray = new boolean[numNodes];
	
			tempVisitedArray[paraStartIndex] = true;
	
			// Initialize the queue.
			// Visit before enqueue.
			tempVisitedArray[paraStartIndex] = true;
			resultString += paraStartIndex;
			tempQueue.enqueue(new Integer(paraStartIndex));
	
			// Now visit the rest of the graph.
			int tempIndex;
			Integer tempInteger = (Integer) tempQueue.dequeue();
			AdjacencyNode tempNode;
			while (tempInteger != null) {
				tempIndex = tempInteger.intValue();
	
				// Enqueue all its unvisited neighbors. The neighbors are linked
				// already.
				tempNode = headers[tempIndex].next;
				while (tempNode != null) {
					if (!tempVisitedArray[tempNode.column]) {
						// Visit before enqueue.
						tempVisitedArray[tempNode.column] = true;
						resultString += tempNode.column;
						tempQueue.enqueue(new Integer(tempNode.column));
					} // Of if
					tempNode = tempNode.next;
				} // Of for i
	
				// Take out one from the head.
				tempInteger = (Integer) tempQueue.dequeue();
			} // Of while
	
			return resultString;
		}// Of breadthFirstTraversal
	
		/
		/**
		 * 
		 ***********************************
		 * @Title: breadthFirstTraversalTest   
		 * @Description:  Unit test for breadthFirstTraversal. The same as the one in class Graph.
		 * @param:       
		 * @return: void       
		 ***********************************
		 */
		public static void breadthFirstTraversalTest() {
			// Test an undirected graph.
			int[][] tempMatrix = { { 0, 1, 1, 0 }, { 1, 0, 0, 1 }, { 1, 0, 0, 1 }, { 0, 1, 1, 0 } };
			graph1 tempGraph = new graph1(tempMatrix);
			System.out.println(tempGraph);
	
			String tempSequence = "";
			try {
				tempSequence = tempGraph.breadthFirstTraversal(2);
			} catch (Exception ee) {
				System.out.println(ee);
			} // Of try.
	
			System.out.println("The breadth first order of visit: " + tempSequence);
		}// Of breadthFirstTraversalTest
	
		/**
		 * 
		 ***********************************
		 * @Title: main   
		 * @Description:  The entrance of the program.
		 * @param: @param args      
		 * @return: void       
		 ***********************************
		 */
		public static void main(String args[]) {
			int[][] tempMatrix = { { 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 } };
			AdjacencyList tempTable = new AdjacencyList(tempMatrix);
			System.out.println("The data are:\r\n" + tempTable);
	
			breadthFirstTraversalTest();
		}// Of main
	
	}// Of class AdjacencyList

 

3. 总结

在广度优先遍历中,将以前for循环遍历每一个节点,再挨个寻找每个不为0的边,改成while(tempNode != null),直接就判定了下一个节点与其是否存在相连的边。但是改成了while,它还是挨个在向下遍历不为0的边啊,和以前for循环中的continue效果不是一样的吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值