简体   繁体   中英

List all link of friends between two given Friends

It is said that all people on average are six, or fewer, social connections away from each other. Create an app that helps you find the degree of separation between any two people. Think of it as selecting two users on Facebook and trying to see how these two people are connected.

If you select any two people, you should be able to see the degrees of separation between them. For example, if you have the following relationships added into your system...

  • Sameer is a Friend of Aayushi
  • Aayushi is a Friend of Bhaskar
  • Sameer is a Friend of Kamalnath Sharma
  • Kamalnath Sharma is a Friend of Shanti Kumar Saha
  • Shanti Kumar Saha is a Friend of Bhaskar

If you select two people, let's say Sameer and Bhaskar, the application should show the degree of separation as follows.

  • Sameer > Aayushi > Bhaskar
  • Sameet > Kamalnath Sharma > Shanti Kumar Saha > Bhaskar

I have to implement this logic in Node.js application! I tried different methods using graph linklist but can't find the solution to implement this.

I used recursion I tried DFS but I was not able to implement it

  var ok = true;
  while(ok){
  for(var i in Data){
   if(Data[i].name == value1){
       for(var j in Data[i].friends){
            if(Data[i].friends[j] == value2){
               path.push(Data[i].friends[j])
               ok = false;
               }else{
                        find(Data[i].friends[j],value2,path)
                    }
                }
            }
        }
        }
    }

Reading the answer you posted (in the future you could probably just edit your post), you pretty much got it. You could make the DFS more efficient by preprocessing your JSON into an adjacency list Graph, and you could avoid infinite loops by keeping track of which friends you've visited before (so you don't visit them multiple times and loop around infinitely).

An adjacency list Graph is just a representation of a Graph where you store in an object a list of vertices as keys, and a list of all other vertices they're adjacent (connected) to as the values. For example, the Graph would have the key "sameer" mapped to the list ["aayushi", "kamalnath"] . This makes it so that every time you call find , you don't have to loop over all of Data to find value1 . You could just find the friends of value1 by doing Graph[value1] . (I renamed value1 to source and value2 to target along with a few other variable name changes in the code below for clarity).

As for avoiding loops, you can track friends you've already visited in a simple javascript Object (or set), initialized as empty and added to as you visit each new friend at the start of the recursive call, then just pass this Object down each recursive call. You check it at the start of each call to make sure you aren't entering into a loop. This isn't necessary for DFS/BFS searches you perform on trees (which are by definition acyclic Graphs), but it's needed for general Graphs which might have loops/cycles.

One other minor thing is when you find your target value/friend, you have

if(Data[i].friends[j] == value2){
  path.push(Data[i].friends[j])
  break;
}

You're right not to recurse in this case, but you probably don't want to break if you want to be able to continue to search the other friends you're looping over for alternate paths (rather than just breaking and returning the first path you find).

Also, I'm not sure if this is intentional, but in the example data it looks like friendships are one-way (eg shanti is a friend of bhaskar, but bhaskar has no listed friends). If they're meant to be 2 way you would probably change how you preprocess the connections list into a Graph slightly. Anyways, here is code with all the changes I mentioned. If it's not clear let me know:

 // preprocess a JSON list of connections to an adjacency list Graph function connectionsListToGraph(connections) { const Graph = {} for (let { name, friends } of connections) { Graph[name] = friends // allow fast lookup of a given person's friends } return Graph } // return the list of connections between source and target function getConnections(source, target, connections) { const Graph = connectionsListToGraph(connections) const connectionPaths = [] function findConnectionsDFS(source, target, path = [source], visited = {}) { // Don't search/visit the same friend twice (to avoid infinite loops) if (visited[source]) return; // mark that we've searched the current source friend visited[source] = true; for (let friend of Graph[source]) { if (friend === target) { connectionPaths.push(path.concat(target)); } else { findConnectionsDFS(friend, target, path.concat(friend), visited) } } } findConnectionsDFS(source, target); return connectionPaths; } let connections = [ { "name": "sameer", "friends": ["aayushi", "kamalnath"] }, { "name": "aayushi", "friends": ["bhaskar"] }, { "name": "kamalnath", "friends": ["shanti"] }, { "name": "shanti", "friends": ["bhaskar"] } ] console.log('Sameer to Bhaskar:', getConnections('sameer', 'bhaskar', connections)) console.log('Kamalnath to Bhaskar:', getConnections('kamalnath', 'bhaskar', connections))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM