package structure;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
//邻接链表表示的图
public class AdjacencyListGraph {
private LinkedList<LinkedList<GraphListNode>> vertexList;//点链表
public LinkedList<LinkedList<GraphListNode>> getVertexList() {
return vertexList;
}
//图中是否包含某个顶点
public boolean contains(int vertex){
Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()) {
//如果当前顶点的边链表已经存在,直接返回
if (itr.next().get(0).getVertex() == vertex) {
return true;
}
}
return false;
}
public AdjacencyListGraph(){
this.vertexList = new LinkedList<LinkedList<GraphListNode>>();
}
//增加一个顶点
public void addVertexSingle(int vertexNo){
if (contains(vertexNo)) {
return;
}
//定义一个以vertexNo为头的边链表
LinkedList<GraphListNode> ll = new LinkedList<GraphListNode>();
ll.add(new GraphListNode(vertexNo,0));
//将边链表加入到点链表中
vertexList.add(ll);
}
//单向删除一个顶点
public void deleteVertexSingle(int vertexNo){
Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()) {
//找到相应点对应的边链表,删除
LinkedList<GraphListNode> ll = itr.next();
if (ll.get(0).getVertex() == vertexNo) {
itr.remove();
break;
}
}
}
//双向删除一个顶点
public void deleteVertexDouble(int vertexNo){
Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()) {
//找到相应点对应的边链表,删除
LinkedList<GraphListNode> ll = itr.next();
if (ll.get(0).getVertex() == vertexNo) {
itr.remove();
break;
}
}
itr = vertexList.listIterator();
//删除所有的相关记录
while(itr.hasNext()){
LinkedList<GraphListNode> ll = itr.next();
Iterator<GraphListNode> li = ll.listIterator();
while (li.hasNext()) {
if (li.next().getVertex() == vertexNo) {
li.remove();
}
}
}
}
//双向增加
public void addEdgeDouble(int vertexNoU,int vertexNoV){
addEdgeDouble(vertexNoU, vertexNoV, 0);
}
public void addEdgeDouble(int vertexNoU,int vertexNoV,int weight){
updateEdge(vertexNoU, vertexNoV, weight);
updateEdge(vertexNoV, vertexNoU, weight);
}
//增加一个不带权重的从u到v的边
public void addEdgeSingle(int vertexNoU,int vertexNoV){
updateEdge(vertexNoU, vertexNoV,0);
}
public void addEdgeSingle(int vertexNoU,int vertexNoV,int weight){
updateEdge(vertexNoU, vertexNoV,weight);
}
//增加或修改一条从u到v,权重为weight的边
public void updateEdge(int vertexNoU,int vertexNoV,int weight){
Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()) {
//检测以vertexNoU为顶点的边链表是否存在
LinkedList<GraphListNode> ll = itr.next();
if (ll.get(0).getVertex() == vertexNoU) {
//检测在该边链表中是否已经存在从u到v的边
Iterator<GraphListNode> it = ll.listIterator();
while (it.hasNext()) {
if (it.next().getVertex() == vertexNoV) {
//如果已经存在该边,直接更新权重
it.next().setWeight(weight);
return;
}
}
//如果不存在该边,则增加该边
ll.add(new GraphListNode(vertexNoV, weight));
return;
}
}
//如果不存在顶点vertexNoU,增加顶点U,然后增加边uv
addVertexSingle(vertexNoU);
updateEdge(vertexNoU, vertexNoV, weight);
}
//双向设置标记
public void setMarkDouble(int vertexNo,boolean flag){
ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()){
LinkedList<GraphListNode> ll = itr.next();
for (GraphListNode gln: ll) {
if (gln.getVertex() == vertexNo) {
gln.setVisited(flag);
}
}
}
}
//在进行遍历前,清除所有标记
public void clearAllMark(){
ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()){
LinkedList<GraphListNode> ll = itr.next();
for (GraphListNode gln: ll) {
gln.setVisited(false);
}
}
}
public void DFS(int startVertex){
clearAllMark();
depthFirstSearch(startVertex);
}
//深度优先搜索
public void depthFirstSearch(int startVertex){
boolean isExisted = false;
ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()) {
//检测以startVertex为顶点的边链表是否存在
LinkedList<GraphListNode> ll = itr.next();
if (ll.get(0).getVertex() == startVertex) {
isExisted = true;
//进行深度优先搜索
Iterator<GraphListNode> it= ll.listIterator();
//跳过第一个顶点并设置第一个顶点为以遍历
System.out.print(startVertex+" ");
GraphListNode gln = it.next();
setMarkDouble(startVertex, true);
while (it.hasNext()) {
gln = it.next();
//如果未访问,则进行深度搜索
if (!gln.isVisited()) {
depthFirstSearch(gln.getVertex());
setMarkDouble(gln.getVertex(), true);
}
}
break;
}
}
if (!isExisted) {
System.out.println(startVertex+" is not exists in this graph");
}
}
public void BFS(int startVertex){
clearAllMark();
breadthFirstSearch(startVertex);
}
//广度优先搜索
public void breadthFirstSearch(int startVertex){
boolean isExisted = false;
ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
//使用链表模仿队列
LinkedList<Integer> store = new LinkedList<Integer>();
isExisted = contains(startVertex);
if (!isExisted) {
System.out.println(startVertex+" is not exists in this graph");
}
//进行广度优先搜索
else {
//压入队列并设置为已遍历,初始化队列
store.offer(startVertex);
setMarkDouble(startVertex, true);
while (!store.isEmpty()) {
int current = store.poll();
//打印当前顶点
System.out.print(current+" ");
//找出当前顶点对应的边链表
itr = vertexList.listIterator();
while(itr.hasNext()) {
LinkedList<GraphListNode> ll = itr.next();
if (ll.get(0).getVertex() == current) {
Iterator<GraphListNode> it = ll.listIterator();
//跳过第一个
it.next();
while (it.hasNext()) {
//将该顶点的所有相邻顶点压入队列
GraphListNode gln = it.next();
if (!gln.isVisited()) {
store.offer(gln.getVertex());
setMarkDouble(gln.getVertex(), true);
}
}
}
}
}
}
}
//判断两个点是否联通
//这里由于程序的限制,测试中一般只能测试是否直接相连
public boolean isConnected(int src,int des){
//递归终止条件
Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
while(itr.hasNext()) {
//找到点U
LinkedList<GraphListNode> ll = itr.next();
if (ll.get(0).getVertex() == src) {
Iterator<GraphListNode> it = ll.listIterator();
//跳过它自身
it.next();
while (it.hasNext()) {
src = it.next().getVertex();
if (src == des) {
return true;
}
//恢复迭代器
itr = vertexList.listIterator();
}
}
}
return false;
}
//打印邻接链表
public void printAllLinkedlist(){
for (LinkedList<GraphListNode> ll : vertexList) {
for (GraphListNode gln : ll) {
//权重为0则不打印
if (gln.getWeight() == 0) {
System.out.print(gln.getVertex()+" ");
}
else{
System.out.print(gln.getVertex()+"("+gln.getWeight()+") ");
}
}
System.out.println();
}
}
/**
* Kuruskal算法:根据边找出最小生成树
* Prim算法:根据点找出最下生成树
* Dijkstra算法:每次处理一个顶点,最终得到从某一顶点到所有其他顶点的最短路径
* 省略
* */
public static void main(String[] args) {
//建立一个无向图
/* AdjacencyListGraph alg = new AdjacencyListGraph();
alg.addEdgeDouble(1,3);
alg.addEdgeDouble(1,5);
alg.addEdgeDouble(2,3);
alg.addEdgeDouble(2,6);
alg.addEdgeDouble(3,4);
alg.addEdgeDouble(3,6);
alg.addEdgeDouble(5,6);
alg.addEdgeDouble(7, 4);
alg.printAllLinkedlist();
System.out.println("--------------");
alg.deleteVertexDouble(1);
alg.printAllLinkedlist();
System.out.println("--------------");
alg.addVertexSingle(1);
alg.addEdgeDouble(1, 3);
alg.addEdgeDouble(1, 5);
alg.printAllLinkedlist();
System.out.println("--------------");
alg.DFS(1);
System.out.println("\n--------------");
alg.BFS(1);
//System.out.println(alg.isConnected(1, 4));
//增加有向边,并设置权重
alg.addEdgeSingle(1,2,10);
alg.addEdgeSingle(1,3,3);
alg.addEdgeSingle(1,4,20);
alg.addEdgeSingle(3,2,2);
alg.addEdgeSingle(2,4,5);
alg.addEdgeSingle(3,5,15);
alg.addEdgeSingle(4,5,11);
alg.printAllLinkedlist();
*/
}
}