F#实现图的广度遍历

  继上一篇的深度遍历,下面实现以下图的广度遍历,广度遍历中使用到了队列, 即代码中的

let nodesQueue = new Queue<Node>(),由于F# 中没有指针,如果我们需要在递归中保存一个随时会发生变化的值时,我会选择ref类型的变量。

  下面顺便说说ref类型变量的一些基本操作:

let x = ref 1

  定义一个ref类型的变量

let getValue = !x

  !x用来获取此ref变量的值,这里将其值赋给了getValue变量

x := 2

  将x 的值变为2

let newValue = !x

  这里,变量newValue的值就是2了。

接下来就是此遍历的具体代码了,没有什么新的东西:)

type GraphOperations(graph : Graph) =

    member this.BFSTraverse(action : unit -> unit, startNodeId : string, endNodeId : string) = 
        let visited : string array = Array.zeroCreate graph.Nodes.Length 
        let visitIndex = ref 0  
        //queue of visited nodes                     
        let nodesQueue = new Queue<Node>()
        let startNode = ref Unchecked.defaultof<Node>
        try
            startNode := graph.Nodes |> List.find(fun item -> item.ID = startNodeId)                        
        with
            | _ -> printfn "There is no such node"
        nodesQueue.Enqueue(!startNode)
        if ((!startNode).ID = endNodeId) then                
            action()//defined by user, what you want to do when find the target?
        else
            visited.[!visitIndex] <- (!startNode).ID                    
            visitIndex := !visitIndex + 1
            while(nodesQueue.Count <> 0) do
                let node = nodesQueue.Dequeue()                         
                let adjNodes = node.OutgoingEdges |> List.map(fun xNode -> xNode.ToNode)
                let freshAdjNodes = 
                    adjNodes 
                        |> List.filter(fun adjnode ->not (visited |> Array.exists(fun x -> x = adjnode.ID)))
                let mutable foundFlag = false
                let index = ref 0
                while (!index < freshAdjNodes.Length && foundFlag = false) do
                    if(freshAdjNodes.[!index].ID = endNodeId) then
                        action()
                        foundFlag <- true
                    else
                        visited.[!visitIndex] <- freshAdjNodes.[!index].ID
                        visitIndex := !visitIndex + 1
                        nodesQueue.Enqueue(freshAdjNodes.[!index])
                        index := !index + 1     


留个笔记~:)

posted @ 2012-11-08 18:15  ZackZhou  阅读(1218)  评论(0编辑  收藏  举报