简体   繁体   中英

How to implement add operation in Binary Search Tree in F#?

I am trying to implement the following code from Algorithms 4th Edition

private Node put(Node x, Key key, Value val)
{
    if (x == null) return new Node(key, val, 1);
    int cmp = key.compareTo(x.key);
    if (cmp < 0) x.left = put(x.left, key, val);
    else if (cmp > 0) x.right = put(x.right, key, val);
    else x.val = val;
    x.N = size(x.left) + size(x.right) + 1;
    return x;
}

I have come up with following implementation in F#:

type Node = {
                mutable Left : Node option
                mutable Right : Node option
                mutable Value : int
                mutable Count : int
            }

type BST() =
    let root : Node option = None

    member x.Put (value : int) =
        let rec Add (node:Node option) value =
            match node with 
            | None -> Some { Left = None; Right = None; Value = value; Count = 1 }
            | Some t -> 
                match t with
                | _ when t.Value < value ->  t.Right <- Add t.Right value
                | _ when t.Value > value -> t.Left <- Add t.Left value
                | _ -> 
                        t.Value <- value
                        t.Count <- (x.Size t.Left) + (x.Size t.Right) + 1
                        Some t
        ()

I am getting error : expected to have type Node option but here as unit, in the following lines:

| _ when t.Value < value ->  t.Right <- Add t.Right value
| _ when t.Value > value -> t.Left <- Add t.Left value

Is there a better way to implement the above code? Am I making a mistake by copying a procedural style code as it is in functional approach?

You are getting the error because the None match returns Some Node , so you have to match that return type in all other branches.

You can address that issue in the other matches by returning the node after matching on it:

let rec Add (node:Node option) value =
    match node with 
    | None -> Some { Left = None; Right = None; Value = value; Count = 1 }
    | Some t -> 
        match t with
        | _ when t.Value < value ->
            t.Right <- Add t.Right value
            Some t
        | _ when t.Value > value ->
            t.Left <- Add t.Left value
            Some t
        | _ ->
            t.Value <- value
            //t.Count <- (x.Size t.Left) + (x.Size t.Right) + 1
            Some t

(You may notice that I commented out the penultimate line, because x has no Size member.)

Am I making a mistake by copying a procedural style code as it is in functional approach?

Probably. That depends on what your goal is. If you want to learn the syntax of F#, it may be a good exercise. If you want to learn Functional Programming, there's no point in doing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM