• 一个别人问我的多叉树的问题....


    问题描述:

    这是她的项目里的一个需求好像要做什么聚类的,但是我不太懂,只是用我的思路解决了问题...

    输入:

    一个字符串数组,数组中的每个字符串的格式为A B,AB中间有一个空格,A和B是源IP和目的IP.

    输出:

    输出所有的A B B C C D形式的串,即数组中的字符串的后半部分和另一个字符串的前半部分相同的话就要成一条链,但是扫描到一个字符串的时候不用考虑他前面串是否满足该特性.

    我的思路:

    这个问题可以用多叉树来做,为每一个根结点创建一个树(用哈希表防止重复建树和关键节点,这个很重要),读入数组后根据条件建立一个多叉树,然后用深度优先搜索遍历并保存每一条路径,就是要的结果,时间复杂度为O(n2),应该还有更好的方案,但是我智商捉急,只能想到O(n2)复杂度的算法,另外二叉树的深度优先非递归写法在保存路径时节点回退我没有想到解决方案,就改写成了递归方法,否则可以用一个栈来做.

    借用数据结构:

    HashMap:根据字符串的值来当哈希键值,用来存储一个串的节点是否被访问过,以防止多建了树。

    Stack:非递归深搜二叉树的时候要用到.

      1 package help.myz;
      2
      3 import java.util.ArrayList;
      4 import java.util.HashMap;
      5 import java.util.Stack;
      6 
      7 
      8 
      9 
     10 class MultiTreeNode
     11 {//多叉树
     12     //MultiTreeNode parent = null; //父节点,为了扫描树深搜回退节点的去除字符串的时候用
     13     String str = null;//当前字符串的值
     14     //boolean isIntree = false; //标志该节点是否已经被填入到一颗树中,如果添加到过就不用添加了
     15     
     16     ArrayList<MultiTreeNode> childList = new ArrayList<>();//所有的孩子节点
     17     public MultiTreeNode(String str) {
     18         // TODO Auto-generated constructor stub
     19         this.str = str;
     20     }
     21 }
     22 
     23 public class MultiTree {
     24     
     25     ArrayList<MultiTreeNode> treeList = new ArrayList<>(); //存储所有的树
     26     HashMap<String, MultiTreeNode> treeMap = new HashMap<>(); //记录字符串是否被扫描过
     27     
     28     ArrayList<String> tmpStrList = new ArrayList<>(); //存储扫描树的某条路径时过程中的中间串
     29     
     30     public void treeBuild(ArrayList<String> strlist)
     31     {
     32         int index = 0,i;
     33         for(i = 0; i < strlist.size(); i++)
     34         {
     35             String currentString = strlist.get(i);
     36             MultiTreeNode currentNode = treeMap.get(currentString);
     37             
     38             if(currentNode == null)
     39             {
     40                 //System.out.print("build a tree");
     41                 currentNode = new MultiTreeNode(currentString);//创建新的节点
     42                 treeMap.put(currentString, currentNode); //把当前节点加入到哈希表
     43                 treeList.add(currentNode); //让该节点重新创建一颗树
     44             }
     45             
     46             /*更新树,查找当前节点后面的节点是否有其后续链*/
     47             index  = i + 1;
     48             for(; index < strlist.size(); index++)
     49             {
     50                 String strBack = currentString.split(" +")[1];//获取字符串的后半部分
     51                 String strForward = strlist.get(index).split(" +")[0];//获取字符串的前半部分
     52                 
     53                 if(strBack.equals(strForward))
     54                 {//该节点满足条件AB BC
     55                     MultiTreeNode childNode = new MultiTreeNode(strlist.get(index));//创建新字符串的孩子节点
     56                     treeMap.put(strlist.get(index), childNode);//将扫描到的当前孩子节点也加入哈希表,防止二次建树
     57                     
     58                     currentNode.childList.add(childNode);//给当前树的当前节点添加孩子节点
     59                 }
     60             }
     61         }
     62     
     63     }
     64     
     65     /*
     66      *递归深度优先遍历树,并生成路径 
     67      */
     68     public void treeScan_ReCursion(MultiTreeNode root)
     69     {
     70         this.tmpStrList.add(root.str);//将当前字符串加入临时存储表
     71         
     72         if(root.childList.size() == 0)
     73         {//当前节点为叶子节点,扫描完一条路径,保存该路径
     74             ArrayList<String> pathStrList = new ArrayList<>(this.tmpStrList);
     75             
     76             PrintPathList(pathStrList);
     77             //PrintPathList(tmpStrList);
     78         }
     79         
     80         for(int i = 0; i < root.childList.size(); i++)
     81         {//递归扫描所有孩子节点
     82             treeScan_ReCursion(root.childList.get(i));
     83         }
     84         
     85         this.tmpStrList.remove(this.tmpStrList.size() - 1);//节点回退上一层的时,回退一个字符串
     86     }
     87     
     88     /*
     89      * 非递归深度优先遍历当前树,并生成路径
     90      */
     91     /*
     92     public void treeScan(MultiTreeNode root)
     93     {
     94         ArrayList<String> tmpList = new ArrayList<>();//存储深搜的过程值
     95         
     96         Stack<MultiTreeNode> treeStack = new Stack<>();
     97         
     98         treeStack.add(root);
     99         
    100         while(!treeStack.isEmpty())
    101         {//当前树未扫描完
    102             MultiTreeNode currentNode = treeStack.pop(); //获取栈顶值
    103             int nodeChildNum = currentNode.childList.size();
    104             tmpList.add(currentNode.str);//将当前的字符串加入中间结果
    105             
    106             if(nodeChildNum == 0)
    107             {//当前节点为叶子节点
    108                 ArrayList<String> currentStrList = new ArrayList<>(tmpList);//存储当前扫描完的一条路径的串
    109                 //System.out.println(currentStrList);//打印当前链 
    110                 PrintPathList(currentStrList);
    111                 tmpList.remove(tmpList.size() - 1); //回退一个字符串,为了继续搜索其他路径
    112             }
    113             
    114             
    115             if(currentNode.parent != null)
    116             {//父节点不为空
    117                 ArrayList<MultiTreeNode> brotherList = currentNode.parent.childList;//所有的兄弟节点链表
    118                 MultiTreeNode finalBrotherNode = brotherList.get(brotherList.size() - 1);//获取当前节点的最后一个兄弟节点
    119                 if(currentNode == finalBrotherNode)
    120                 {//访问完当前层的最后一个节点,还需要回退一个节点
    121                     tmpList.remove(tmpList.size() - 1);
    122                 }
    123             }
    124             
    125             
    126             for(int i = nodeChildNum - 1; i >= 0; i--)
    127             {
    128                 treeStack.push(currentNode.childList.get(i)); //将其他孩子按照从后到前的顺序入栈
    129             }
    130             
    131         }
    132     }
    133     */
    134     
    135     /*
    136      *扫描所有树 
    137      */
    138     public void treeListScan()
    139     {//将所有树扫描出来
    140         for(int i = 0; i < treeList.size(); i++)
    141         {
    142             MultiTreeNode treeRoot = treeList.get(i); //获取当前树的根
    143             //treeScan(treeRoot);
    144             treeScan_ReCursion(treeRoot);
    145         }
    146     }
    147     
    148     public void PrintPathList(ArrayList<String> pathStrList)
    149     {
    150         for(int i = 0; i < pathStrList.size(); i++)
    151         {
    152             System.out.print(pathStrList.get(i) + "-->");
    153         }
    154         
    155         System.out.println();
    156         System.out.println("--------------------------");
    157     }
    158     
    159     public static void main(String[] args) {
    160         // TODO Auto-generated method stub
    161         MultiTree multiTree = new MultiTree();
    162         String strArray[] = {
    163                 "2886758962 2886758450",
    164                 "2886758450 2886759119",
    165                 "2886758962 2886758607",
    166                 "2886758962 2886758740",
    167                 "2886758450 2886759080",
    168                 "2886758962 2886758500",
    169                 "2886758607 2886758500",
    170                 "2886758962 2886758594",
    171                 "2886758450 2886758594",
    172                 "2886758450 2886759081",
    173                 "2886758962 2886759081",
    174                 "2886758450 2886758860",
    175                 "2886758450 3290778526",
    176                 "2886758607 3290778526",
    177                 "2886759060 3290778526",
    178                 "2886759119 3290778526",
    179                 "2886758450 2886758549",
    180                 "2886758500 2886758420",
    181                 "2886758962 2886758706",
    182                 "2886758420 2886758706",
    183                 "2886758594 2886758706",
    184                 "2886758500 2886758706",
    185                 "2886758740 2886758706"
    186                 };
    187         
    188         String strArray2[] = {
    189                 "A B",
    190                 "B C",
    191                 "C D",
    192                 "A E",
    193                 "B F",
    194                 "D K"
    195         };
    196         
    197         ArrayList<String> strlist = new ArrayList<>();
    198         
    199         for(int i = 0; i < strArray.length; i++)
    200         {
    201             strlist.add(strArray[i]);
    202         }
    203         
    204         multiTree.treeBuild(strlist);
    205         //System.out.println("treeNum is " + multiTree.treeList.size());
    206         multiTree.treeListScan();
    207     }
    208 
    209 }
  • 相关阅读:
    QT添加托盘代码
    2010年左右我说要做一个操作系统的时候,绝大多数人以为那是天方夜谭,是堂吉诃德式的行为。今天,我们讨论YunOS会成为一个新的生态和创新平台,更多人相信这件事是可能的。
    台哥算法练习:八皇后问题
    台哥算法练习 汉诺塔问题
    台哥算法练习:数组排序的几种算法
    面试遇到的两道算法题
    台哥算法练习 50人围圈报数
    台哥算法练习 自己写的一个LinkedList
    台哥算法练习 自己写的一个ArrayList
    台哥算法练习 寻找和为某值的子集
  • 原文地址:https://www.cnblogs.com/daimadebanyungong/p/5056410.html
Copyright © 2020-2023  润新知