采用邻接表法从无向图中获取与目标关联的所有元素

给定一个二维数组 arr 和一个目标 target,从数组中找出和 target 关联的所有元素。

示例1:

给定一个列表如下,[1,2] 表示 1 和 2 具有关联性

输入:arr=[[1,2],[3,4],[9,4],[4,5],[4,6],[4,7],[7,11],[6,12],[11,15]],target=4
输出:3,4,5,6,7,9,11,12,15
解释:这些数字都具有关联性

对于关联性问题,可以采用无向图的思路进行解决

c# 代码如下

internal class Program
{
    static void Main(string[] args)
    {
        InitAdjacencyList(InitAssociations(3));// 改变参数测试其他用例
        long target = 0;
        while (true)
        {
            Console.WriteLine("请输入查找的节点:");
            string value = Console.ReadLine();
            long.TryParse(value, out target);

            HashSet<long> set = new HashSet<long>();
            HashSet<long> foundList = new HashSet<long>();
            Dictionary<long, ListNode<long>> dict = AdjacencyList;
            if (dict != null && dict.Keys.Count > 0)
            {
                FindAssoData(ref set, dict, target, ref foundList);
            }
            set.Remove(target);
            set = set.OrderBy(x => x).ToHashSet();
            Console.WriteLine($"和 {target} 相连的节点为:" + string.Join(",", set));

        }


    }




    /// <summary>
    /// 找到和 target 具有关联的所有结果,广度优先,时间复杂度 nlog(n)
    /// </summary>
    /// <param name="set"></param>
    /// <param name="dict"></param>
    /// <param name="target"></param>
    /// <param name="foundList"></param>
    private static void FindAssoData(ref HashSet<long> set, Dictionary<long, ListNode<long>> dict, long target, ref HashSet<long> foundList)
    {

        if (foundList.Contains(target)) return;
        foreach (long key in dict.Keys)
        {
            if (key.Equals(target))
            {
                ListNode<long> head = dict[target].Head;
                ListNode<long> node = head.Next;
                while (node != null)
                {
                    set.Add(node.Data);
                    node = node.Next;
                }

            }
            else
            {
                // 遍历链表,找到符合 target 的节点
                ListNode<long> head = dict[key].Head;
                bool found = false;
                ListNode<long> node = head.Next;
                while (node != null)
                {
                    if (node.Data == target)
                    {
                        found = true;
                        break;
                    }
                    else
                    {
                        node = node.Next;
                    }
                }
                if (found)
                {

                    set.Add(key);
                    node = head.Next;
                    while (node != null)
                    {
                        set.Add(node.Data);
                        node = node.Next;
                    }

                }
            }
        }
        foundList.Add(target);
        // bfs
        foreach (long item in set.ToArray())
        {
            FindAssoData(ref set, dict, item, ref foundList);
        }
    }






    public static Dictionary<long, ListNode<long>> AdjacencyList { get; set; }


    public static List<Association> InitAssociations(int idx = 0)
    {
        List<Association> Associations = new List<Association>();
        if (idx == 0)
        {
            /**   dict   ***
             * 1->2
             * 3->4
             * 9->4
             * 4->5->6->7
             * 7->11
             * 6->12
             * 11->15
             * 
             * target=4 => 3,4,5,6,7,9,11,12,15
             */
            Associations.Add(new Association(1, 2));
            Associations.Add(new Association(3, 4));
            Associations.Add(new Association(9, 4));
            Associations.Add(new Association(4, 5));
            Associations.Add(new Association(4, 6));
            Associations.Add(new Association(4, 7));
            Associations.Add(new Association(7, 11));
            Associations.Add(new Association(6, 12));
            Associations.Add(new Association(11, 15));
        }
        else if (idx == 1)
        {
            /**   dict   ***
             * 1->2
             * 3->4
             * 4->3
             * 5->6->7
             * 7->11
             * 6->12
             * 15->11->12
             * 
             * target=12 => 5,6,7,11,15
             */
            Associations.Add(new Association(1, 2));
            Associations.Add(new Association(3, 4));
            Associations.Add(new Association(4, 3));
            Associations.Add(new Association(5, 6));
            Associations.Add(new Association(5, 7));
            Associations.Add(new Association(7, 11));
            Associations.Add(new Association(6, 12));
            Associations.Add(new Association(15, 11));
            Associations.Add(new Association(15, 12));
        }
        else if (idx == 2)
        {
            /**   dict   ***
             * 1->2
             * 3->4
             * 5->6
             * 7->8
             * 
             * target=12 => 5,6,7,11,15
             */
            Associations.Add(new Association(1, 2));
            Associations.Add(new Association(3, 4));
            Associations.Add(new Association(5, 6));
            Associations.Add(new Association(7, 8));
        }
        else if (idx == 3)
        {
            /**   dict   ***
             * 1->2->3->4->5->6->7->8->9-10
             * 3->4
             * 5->6
             * 7->8
             * 11->12
             * 12->15
             * 15->1
             * 16->17->18
             * 19->20->16
             * target=12 => 5,6,7,11,15
             */
            Associations.Add(new Association(1, 2));
            Associations.Add(new Association(1, 3));
            Associations.Add(new Association(1, 4));
            Associations.Add(new Association(1, 5));
            Associations.Add(new Association(1, 6));
            Associations.Add(new Association(1, 7));
            Associations.Add(new Association(1, 8));
            Associations.Add(new Association(1, 9));
            Associations.Add(new Association(1, 10));
            Associations.Add(new Association(3, 4));
            Associations.Add(new Association(5, 6));
            Associations.Add(new Association(7, 8));
            Associations.Add(new Association(11, 12));
            Associations.Add(new Association(12, 15));
            Associations.Add(new Association(15, 1));
            Associations.Add(new Association(16, 17));
            Associations.Add(new Association(16, 18));
            Associations.Add(new Association(19, 20));
            Associations.Add(new Association(19, 16));

        }
        return Associations;
    }


    public static void InitAdjacencyList(List<Association> associations)
    {


        AdjacencyList = new Dictionary<long, ListNode<long>>();
        // 构造邻接表
        // 邻接表适合存储稀疏图(顶点较多、边较少)
        if (associations != null && associations.Count > 0)
        {
            foreach (Association asso in associations)
            {
                long dataId = asso.MainDataID;
                if (AdjacencyList.ContainsKey(dataId))
                {
                    ListNode<long> node = AdjacencyList[dataId];
                    while (true)
                    {
                        if (node.Next == null)
                        {
                            node.Next = new ListNode<long>(asso.SubDataID);
                            break;
                        }
                        else
                        {
                            node = node.Next;
                        }
                    }
                }
                else
                {
                    ListNode<long> node = new ListNode<long>(asso.SubDataID);
                    ListNode<long> head = new ListNode<long>(-1);
                    head.Next = node;
                    node.Head = head;
                    AdjacencyList.Add(dataId, node);
                }
            }
            // 打印邻接矩阵
            foreach (long key in AdjacencyList.Keys)
            {
                StringBuilder builder = new StringBuilder();
                builder.Append($"{key}->");
                ListNode<long> head = AdjacencyList[key].Head;
                ListNode<long> node = head.Next;
                while (node != null)
                {
                    builder.Append($"{node.Data}->");
                    node = node.Next;
                    if (node == null) builder.Remove(builder.Length - 2, 2);
                }
                Console.WriteLine(builder);
            }
        }
        //Console.WriteLine();
    }
}

public class ListNode<T>
{
    public T Data { get; set; }
    public ListNode<T> Next { get; set; }
    public ListNode<T> Head { get; set; }



    public ListNode(T item)
    {
        Data = item;
    }
}

public class Association
{

    public long MainDataID { get; set; }
    public long SubDataID { get; set; }

    public Association(long d1, long d2)
    {
        MainDataID = d1;
        SubDataID = d2;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值