图的基本操作(基于邻接表

public class AdjListGraph<T> extends AbstractGraph<T>{
	protected LinkedMatrix adjlist;//图的邻接表
	public AdjListGraph(int length){
		super(length);//构造长度为length的空顺序表
		this.adjlist = new LinkedMatrix(length,length);//构造length×length矩阵
	}
	
	//以下是构造方法
	public AdjListGraph(){
		this(10);//构造空图,顶点数为0,边数为0,顶点顺序表和邻接矩阵的默认容量是10
	}
	public AdjListGraph(T[] vertices)//以顶点集合vertices构造图
	{
		this(vertices.length);
		for(int i = 0;i<vertices.length;i++){
			this.insertVertex(vertices[i]);
		}
	}
	
	public AdjListGraph(T[] vertices,Triple[] edges){
		//以vertices顶点集合和edges边集合
		this(vertices);
		for(int j = 0;j<edges.length;j++){
			this.insertEdge(edges[i]);
		}
	}
	public String toString(){
		return super.toString()+"出边表:\n"+this.adjlist.toString();
	}
}



基于邻接表的插入边操作

1.weight范围:0到正无穷。如果weight越界,视为无边,取值是0

2.若I、j满足:0≤I,j<图的顶点数,I≠j,则在邻接表第I条边单链表中查找表示<vi,vj>的结点,根据查找结果和weight取值,分别执行插入、替换、删除操作

3.若I、j越界,抛出序号越界异常。若I==j,表示自身环。抛出无效参数异常

public void insertEdge(int i,int j,int weight){
	if(i != j){
		if(weight<0 || weight>=MAX_WEIGHT){
			weight = 0;
		}
		this.adjlist.set(i,j,weight);
	}
	else throw new IllegalArgumentException("不能插入自身环");
}
public void insertEdge(Triple[] edge){
	this.insertEdge(edge.row,edge.column,edge.value);
}

插入顶点操作:

public int insertVertex(T x){
	int i = this.vertexlist.insert(x);
	if(i>=this.adjlist.getRows()){
		this.adjlist.setRowsColumns(i+1,i+1);
	}
	return i;
}
删除边操作
public void removeEdge(int i,int j){
	if(i != j)
		this.adjlist.set(new Triple(i,j,0));//第i条边单链表中删除边结点
}
public void removeEdge(Triple edge){
	this.removeEdge(edge.row,edge.column);
}


删除顶点:

1.在顶点顺序表中删除第I个元素,图顶点数-1

2.在邻接表中删除所有与顶点vi相关联的边,包括以下操作:

   1>在第I条以外的边单链表中,删除所有以顶点I为终点的边结点

   2>在行指针顺序表中,删除第I个元素,即删除第I条边单链表

   3>在所有边单链表中,将边结点中大于I的顶点序号-1

public void removeVertex(int i){
	int n = vertexCount();
	if(i>=0 && i<n){
		SortedSinglyList<Triple> link = this.adjlist.rowlist.get(i);//获取要删除的边单链表
		for(Node<Triple> p = link.head.next; p != null;p = p.next){
			this.removeEdge(p.data.toSymmetry());//删除与p结点对称的边
		}
		n--;//顶点数-1
		this.adjlist.rowlist.remove(i);//删除行指针顺序表的第i条边单链表,其后单链表上移
		this.adjlist.setRowsColumns(n,n);//设置矩阵行列数,少一行
		for(int j = 0;j<n;j++){
			link = this.adjlist.rowlist.get(j);
			for(Node<Triple> p = link.head.next; p != null; p = p.next){
				if(p.data.row>i){
					p.data.row--;
				}
				if(p.data.column>i){
					p.data.column--;
				}
			}
		}
		this.vertexlist.remove(i);
	}
	else throw new IndexOutOfBoundsException("i="+i);
}



基于邻接表,我们可以对进行以下基本操作: 1. 添加节点:在邻接表中添加一个新的节点,需要把数组的长度增加1,并在数组中添加一个新的元素,表示新的节点。同时,需要把新节点的邻居链表初始化为空。 2. 添加边:在邻接表中添加一条边,需要更新起点和终点的邻居链表。具体来说,我们创建一个新的节点,把它插入起点的邻居链表头部,然后再创建一个节点,把它插入终点的邻居链表头部。 3. 删除节点:在邻接表中删除一个节点,需要把数组中对应的元素删除,并把所有指向该节点的边都删除。 4. 删除边:在邻接表中删除一条边,需要在起点的邻居链表中找到终点,并把终点从链表中删除。同时,需要在终点的邻居链表中找到起点,并把起点从链表中删除。 5. 搜索节点:在邻接表中搜索一个节点,可以直接访问数组中对应的元素。 6. 搜索路径:在邻接表中搜索两个节点之间的路径,可以使用广度优先搜索或深度优先搜索算法。具体来说,我们可以先对起点进行标记,然后从起点开始进行遍历,直到遍历到终点为止。在遍历的过程中,我们需要记录每个节点的前驱节点,以便在找到终点后,可以通过前驱节点逆向构造出起点到终点的路径。 7. 计算最短路径:在邻接表中计算两个节点之间的最短路径,可以使用 Dijkstra 算法或 Bellman-Ford 算法。这些算法都是基于的权重和邻接表进行设计的,具体实现细节可以参考相关文献。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值