软件构造lab1与lab2中算法的比较

        在lab2中对lab1中的算法进行了替换,下文给出对比。

Lab1:

        在lab1中,利用的是深搜算法计算两个人之间在关系网中的距离。处理流程分两步,为:

        1)先在关系网中搜索这两个人,检查是否存在;

        2)带入深搜算法中,获得距离

        代码如下:

	public int getDistance(Person name1, Person name2)
	{
		if(this.firstperson == null)
		{
			System.out.println("关系网中没有人!");
			return -1;
		}
		else
		{
			Vertex tempPerson1 = this.firstperson;
			do{//找第一个人
				if(tempPerson1.NameString == name1.name)
					break;
				tempPerson1 = tempPerson1.nextperson;
			}while(tempPerson1 != null);
			if(tempPerson1 == null)
			{
				System.out.println("没有找到名为"+name1.name+"的人!");
				return -1;
			}
			
			if(name1.name == name2.name) return 0;
			
			Vertex tempPerson2 = this.firstperson;
			do{//找第二个人
				if(tempPerson2.NameString == name2.name)
					break;
				tempPerson2 = tempPerson2.nextperson;
			}while(tempPerson2 != null);
			if(tempPerson2 == null)
			{
				System.out.println("没有找到名为"+name2.name+"的人!");
				return -1;
			}
			
			int distance = 1,result = 0;
			Friendship tempShip = tempPerson1.friendship;
			if (tempShip == null) return -1;//这个人没有朋友
			
			result = DFS(tempShip, distance, name2.name,name1.name);
			this.reset();
			return result;
			
		}
	}
	
	public int DFS(Friendship tempShip, int distance, String name, String name2)
	{
		boolean flag1 = false, flag2 = false;
		int distance2 = 0,distance1 = 100;
		do {
			if(tempShip.itsfriend.visited ==true)//这个人已经遍历过了
				tempShip = tempShip.nextfriend;//准备遍历下一个朋友
			else//没有遍历过
			{
				if(tempShip.friendsname == name)//找到了
				{
					flag1 = true;
					break;
				}
				else if(tempShip.friendsname == name2)//找到自己了
				{
					tempShip = tempShip.nextfriend;//准备遍历下一个朋友
					continue;
				}
				else//没找到
				{
					tempShip.itsfriend.visited = true;
					distance2 = DFS(tempShip.itsfriend.friendship, distance+1, name,name2);
					if(distance != -1)
					{
						if(flag2 == false) 
						{
							flag2 = true;
							distance1 = distance2;
						}
						else 
						{
							if(distance1 > distance2) distance1 = distance2;
						}
					}
					tempShip = tempShip.nextfriend;//准备遍历下一个朋友
				}
			}
		}while(tempShip != null);//直到搜完这个人的所有朋友
		
		
		if(flag1 == true) 
		{
			if(flag2 == false) return distance;
			else if(distance > distance1) return distance1;
			else return distance;
		}
		else
		{
			if(flag2 == true) return distance1;
			else return -1;
		}
		
	}
	
	public boolean reset()
	{
		Vertex re = this.firstperson;
		if (re == null) return true;
		do
		{
			re.visited = false;
			re = re.nextperson ;
		}while(re != null);
		return true;
	}

        在函数最后还有reset方法,用于重置代表是否访问的标志。

        可以发现,代码量过长,并且写的很繁琐。主要问题在于查找两人是否存在时需要两次遍历关系网,效率低下。

        搜索算法的修改是最为明显的。除此之外还有其他的修改,例如最初的设计中,在FriendshipGraph里建立了多个变量,这些变量实际上使用的次数并不多,但又找不到更好的替代方法。这些都在使用lab2中的图的功能后做出了修改。

    public Vertex lastperson;//保存最后一个人
	public Vertex firstperson;//保存第一个人
	public class Vertex
	{
		String NameString;//存放当前结点的人
		int friendnum = 0;//存放这个人的朋友数量
		Friendship friendship;
		Vertex nextperson;//指向下一个人
		boolean visited = false;
	}
	public class Friendship//存放这个人的关系
	{
		String friendsname;
		Vertex itsfriend;//指向这个人的朋友在关系表中的位置
		Friendship nextfriend;
	}
	
	public FriendshipGraph()
	{
		this.lastperson = null;
		this.firstperson = null;
	}

Lab2:

        lab2使用了在实验前半部分实现的图的各项功能,并且对冗余的遍历进行优化。直接使用contains方法就可以查找,不再需要遍历。

        此外,在lab1中的搜索算法中,每当遍历一个人时,需要在图中找到这个人的结点,然后对它的关系网进行遍历。在lab2中,可以直接使用targets方法直接获得和该点相连接的结点,不再需要遍历操作。

        需要注意的是,函数最后的reset函数也要做些许修改,因为使用的图的构建方式做了修改。

        代码如下:

        

	public int getDistance(Person name1, Person name2)//获得两个人之间的距离
	{
		if(personGraph == null)
		{
			System.out.println("关系网中没有人!");
			return -1;
		}
		else
		{
			//检查有这俩人
			if(personGraph.vertices().contains(name1) && personGraph.vertices().contains(name2))//有这俩人
			{
				if(name1.name == name2.name)//自己与自己的距离
					return 0;
				Person temp = null;//保留第一个人
				for(Person each : personGraph.vertices())
				{
					if(each.name == name1.name)
					{
						temp = each;
						break;
					}
				}
				int result = 0,distance = 1;
				result = DFS(temp, distance, name2.name,name1.name);
				this.reset();
				return result;
			}
			else
				return -1;
				
			
		}
	}
	
	public int DFS(Person temp, int distance, String name, String name2)//深搜,获得距离时使用
	{
		boolean flag1 = false, flag2 = false;
		int distance2 = 0,distance1 = 100;
		Map<Person, Integer> ASsource = new HashMap<>();
		ASsource = personGraph.targets(temp);
		
		for(Person each : ASsource.keySet())
		{
			if(each.visited == true)//这个人已经遍历过了
				continue;
			if(each.name == name)//找到了
			{
				flag1 = true;
				break;
			}
			else
			{
				each.visited = true;
				distance2 = DFS(each,distance+1,name,name2);
				
				if(distance2 != -1)//找到了
				{
					if(flag2 == false) 
					{
						flag2 = true;
						distance1 = distance2;
					}
					else 
					{
						if(distance1 > distance2) distance1 = distance2;
					}
				}
			}
		}
		
		if(flag1 == true) 
		{
			if(flag2 == false) 
			{
				return distance;
			}
			
			else if(distance > distance1) 
			{
				return distance1;
			}
			
			else return distance;
		}
		else
		{
			if(flag2 == true) return distance1;
			else return -1;
		}
		
	}
	
	public boolean reset()//重新设置访问状态,以便于下次使用
	{
		if(personGraph == null)
			return true;
		for(Person each : personGraph.vertices())
		{
			each.visited = false;
		}
		return true;
	}

        针对lab1中的多个低效率变量,也同样做出了修改。由于可以直接调用已实现的代码,大多数变量都进行了删除,并且还简化了图的创建过程、搜寻结点过程和增加结点过程(之前是需要遍历操作的,现在就不需要了)。

private final ConcreteEdgesGraph<Person> personGraph;
	
	public FriendshipGraph() {
		personGraph = new ConcreteEdgesGraph<>();
	}
	
	public boolean searchVertex(Person name)//找这个人
	{
		return personGraph.vertices().contains(name);
	}
	
	public boolean searchFriendship(Person name1,Person name2)//寻找某个人的某个朋友
	{
		if(searchVertex(name1) == false || searchVertex(name2) == false)
			return false;

		Map<Person, Integer> ASsource = new HashMap<>();
		ASsource = personGraph.targets(name1);
		if(ASsource.containsKey(name2))
		{
			return true;
		}
		return false;
	}
	
	public void addVertex(Person name)//增加一个人
	{
		personGraph.add(name);
	}
	
	public void addEdge(Person name1, Person name2)//建立两个人之间的关系
	{
		personGraph.set(name1, name2, 1);
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值