def find_middle_node(doubly):
    """Solution to exercise R-7.8.

    Describe a nonrecursive method for finding, by link hopping, the middle
    node of a doubly linked list with header and trailer sentinels. In the case
    of an even number of nodes, report the node slightly left of center as the
    “middle.” (Note: This method must only use link hopping; it cannot use a
    counter.) What is the running time of this method?

    --------------------------------------------------------------------------
    Solution:
    --------------------------------------------------------------------------
    My solution is to use the doubly linked list's _size parameter to link-hop
    to the middle node of the list.  The running time is O(n), as there will be
    n/2 link hops required to find the middle node.
    """
    if doubly.is_empty():
        return None
    node = doubly._header
    for _ in range((doubly._size-1) // 2 + 1):  # Upper limit excluded, so +1
        node = node._next
    return node