Sunday, January 12, 2014

How to Convert a BST to a Doubly Linked List In-Place

Problem:
Convert a BST to a doubly-linked list in-place. Think of the left and right pointers as synonymous to the previous and next pointers in a doubly-linked list.
package main

import (
    "fmt"
)

type Node struct {
    Value int
    Left  *Node
    Right *Node
}

type LinkedList struct {
    Front *Node
    Back  *Node
}

// this is the actual algorithm that converts a BSt into a doubly linked list
// the rest of the code is just to make unit testing easier
func (l *LinkedList) ToLinkedList(node *Node) {
    if node == nil {
        return
    }
    l.ToLinkedList(node.Left)
    node.Left = l.Back
    if l.Back != nil {
        l.Back.Right = node
    } else {
        l.Front = node
    }
    l.Back = node
    l.ToLinkedList(node.Right)
}

type BST struct {
    Root *Node
}

func (b *BST) Add(value int) {
    b.Root = b.add(b.Root, value)
}

func (b *BST) add(node *Node, value int) *Node {
    if node == nil {
        return &Node{value, nil, nil}
    }
    if node.Value > value {
        node.Left = b.add(node.Left, value)
    } else if node.Value < value {
        node.Right = b.add(node.Right, value)
    }
    return node
}

func main() {
    values := []int{8, 3, 10, 1, 6, 14, 4, 7, 13}
    bst := BST{}
    for _, v := range values {
        bst.Add(v)
    }
    ll := LinkedList{}
    ll.ToLinkedList(bst.Root)
    for n := ll.Front; n != nil; n = n.Right {
        fmt.Print(n.Value, " ")
    }
    fmt.Println()
    for n := ll.Back; n != nil; n = n.Left {
        fmt.Print(n.Value, " ")
    }
    fmt.Println()
}
Output:
1 3 4 6 7 8 10 13 14 
14 13 10 8 7 6 4 3 1

No comments:

Post a Comment