go语言几种算法(四)
19、Floyd–Warshall Algorithm(全源最短路径算法)
package main
import (
"fmt"
"math"
)
type graph struct {
to int
wt float64
}
func floydWarshall(g [][]graph) [][]float64 {
dist := make([][]float64, len(g))
for i := range dist {
di := make([]float64, len(g))
for j := range di {
di[j] = math.Inf(1)
}
di[i] = 0
dist[i] = di
}
for u, graphs := range g {
for _, v := range graphs {
dist[u][v.to] = v.wt
}
}
for k, dk := range dist {
for _, di := range dist {
for j, dij := range di {
if d := di[k] + dk[j]; dij > d {
di[j] = d
}
}
}
}
return dist
}
func main() {
gra := [][]graph{
1: {{2, 3}, {3, 8},{5, -4}},
2: {{4, 1}, {5, 7}},
3: {{2, 4}},
4: {{1, 2}, {3, -5}},
5: {{4, 6}},
}
dist := floydWarshall(gra)
//dist[][] will be the output matrix that will finally
//have the shortest distances between every pair of vertices
for _, d := range dist {
fmt.Printf("%4g\n", d)
}
}
20、Tower of Hanoi Algorithm(汉诺塔)
package main
import "fmt"
type solver interface {
play(int)
}
// towers is example of type satisfying solver interface
type towers struct {
// an empty struct
}
// play is sole method required to implement solver type
func (t *towers) play(n int) {
t.moveN(n, 1, 2, 3)
}
// recursive algorithm
func (t *towers) moveN(n, from, to, via int) {
if n > 0 {
t.moveN(n-1, from, via, to)
t.moveM(from, to)
t.moveN(n-1, via, to, from)
}
}
func (t *towers) moveM(from, to int) {
fmt.Println("Move disk from rod", from, "to rod", to)
}
func main() {
var t solver
t = new(towers) // type towers must satisfy solver interface
t.play(4)
}
21、Huffman Coding(哈夫曼编码)
package main
import (
"container/heap"
"fmt"
)
type HuffmanTree interface {
Freq() int
}
type HuffmanLeaf struct {
freq int
value rune
}
type HuffmanNode struct {
freq int
left, right HuffmanTree
}
func (self HuffmanLeaf) Freq() int {
return self.freq
}
func (self HuffmanNode) Freq() int {
return self.freq
}
type treeHeap []HuffmanTree
func (th treeHeap) Len() int { return len(th) }
func (th treeHeap) Less(i, j int) bool {
return th[i].Freq() < th[j].Freq()
}
func (th *treeHeap) Push(ele interface{}) {
*th = append(*th, ele.(HuffmanTree))
}
func (th *treeHeap) Pop() (popped interface{}) {
popped = (*th)[len(*th)-1]
*th = (*th)[:len(*th)-1]
return
}
func (th treeHeap) Swap(i, j int) { th[i], th[j] = th[j], th[i] }
// The main function that builds a Huffman Tree and print codes by traversing
// the built Huffman Tree
func buildTree(symFreqs map[rune]int) HuffmanTree {
var trees treeHeap
for c, f := range symFreqs {
trees = append(trees, HuffmanLeaf{f, c})
}
heap.Init(&trees)
for trees.Len() > 1 {
// two trees with least frequency
a := heap.Pop(&trees).(HuffmanTree)
b := heap.Pop(&trees).(HuffmanTree)
// put into new node and re-insert into queue
heap.Push(&trees, HuffmanNode{a.Freq() + b.Freq(), a, b})
}
return heap.Pop(&trees).(HuffmanTree)
}
// Prints huffman codes from the root of Huffman Tree. It uses byte[] to
// store codes
func printCodes(tree HuffmanTree, prefix []byte) {
switch i := tree.(type) {
case HuffmanLeaf:
// If this is a leaf node, then it contains one of the input
// characters, print the character and its code from byte[]
fmt.Printf("%c\t%d\t%s\n", i.value, i.freq, string(prefix))
case HuffmanNode:
// Assign 0 to left edge and recur
prefix = append(prefix, '0')
printCodes(i.left, prefix)
prefix = prefix[:len(prefix)-1]
// Assign 1 to right edge and recur
prefix = append(prefix, '1')
printCodes(i.right, prefix)
prefix = prefix[:len(prefix)-1]
}
}
// Driver program to test above functions
func main() {
test := "abcdefghijklmnopqrstuvwxyz"
symFreqs := make(map[rune]int)
// read each symbol and record the frequencies
for _, c := range test {
symFreqs[c]++
}
// example tree
exampleTree := buildTree(symFreqs)
// print out results
fmt.Println("SYMBOL\tWEIGHT\tHUFFMAN CODE")
printCodes(exampleTree, []byte{})
}
发表评论: