遍历、查找

1、递归添加树节点

先找出所有根节点,添加到树,然后根据根节点的id遍历找出所有对应子节点添加到其子节点处。

递归要有跳出条件,方法要自己调用自己。

        List<ClassDG> list = new List<ClassDG>()
        {
            new ClassDG() {ID="0",PID="",name="0" },
            new ClassDG() {ID="1",PID="",name="1" },
            new ClassDG() {ID="2",PID="1",name="2" },
            new ClassDG() {ID="3",PID="1",name="3" },
            new ClassDG() {ID="4",PID="2",name="4" },
            new ClassDG() {ID="5",PID="4",name="5" }
        };

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (ClassDG item in list)
            {
                if (string.IsNullOrEmpty(item.PID))
                {
                    this.treeView1.Nodes.Add(item.ID, item.name);
                }
            }

            for (int i = 0; i < this.treeView1.Nodes.Count; i++)
            {
                AddNodes(treeView1.Nodes[i], treeView1.Nodes[i].Name);
            }
        }

        void AddNodes(TreeNode treenode,string id)
        {
            List<ClassDG> lst = list.Where(p => p.PID.Equals(id)).ToList();
            if (treenode == null || lst.Count == 0)
                return;
            foreach (ClassDG item in lst)
            {
                if (treenode.Name.Equals(item.PID))
                {
                    treenode.Nodes.Add(item.ID, item.name);
                }
                for (int i = 0; i < treenode.Nodes.Count; i++)
                {
                    AddNodes(treenode.Nodes[i], item.ID);
                }
            }
        }

 

2、树的广度优先遍历

先遍历最外围的,如果有子集下次遍历。

        /// <summary>
        /// 树的广度优先遍历
        /// </summary>
        /// <param name="treenodes"></param>
        void PrintNodeWidthFirst(IEnumerable<TreeNode> treenodes)
        {
            //要遍历的下级节点
            List<TreeNode> listNodes = new List<TreeNode>();
            foreach (TreeNode childNode in treenodes)
            {
                //如果节点有子节点则将子节点加入listNodes以备稍后遍历
                if(childNode.Nodes.Count>0)
                {
                    listNodes.AddRange(childNode.Nodes.OfType<TreeNode>());
                }
                
            }
            //如果有待遍历的子节点
            if(listNodes.Count>0)
            {
                PrintNodeWidthFirst(listNodes);
            }
        }

 

3、二分叉查找(针对有序列表)

取中间位索引,如果这个数等于要查找的数则返回,如果不是这个数比要找的数大的话则索引减1,反之在另一边低位为中间位索引加1。循环完毕都没有则没有这个数。

Array有自己内置的二叉查找方法,比用户定制的方法执行速度快10倍。

        int binary_search(List<int> list,int goal)
        {
            int low = 0;
            int high = list.Count - 1;
            while (low <= high)
            {
                //middle = (high - low) / 2 会死循环 所以 如果用减 middle =(high - low) / 2 + low;
                //high:7 low:3 high-low:4 middle=4/2=2 if list[middle]<goal low=middle+1=3 又等于3了 进入前面死循环 middle又等于2 
                //middle = (high + low) / 2 没发现什么问题。
                int middle = (high + low) / 2;
                if (list[middle] == goal)
                    return middle;
                //在左半边
                else if (list[middle] > goal)
                {
                    high = middle - 1;
                }
                    
                //在右半边
                else
                    low = middle + 1;
            }
            //没找到
            return -1;
        }

 

posted @ 2017-05-10 12:52  jechsky  阅读(507)  评论(0编辑  收藏  举报