From: akcs.joehorn@hpcvbbs.cv.hp.com (Joseph K. Horn)
Date: Tue, 25 May 1993 06:40:03 GMT
Subject: Improved Binary Search Algorithm
Message-ID: <2c01baf9.905comp.sys.hp48@hpcvbbs.cv.hp.com>
Path: cdc486.cdc.polimi.it!ghost.dsi.unimi.it!batcomputer!caen!spool.mu.edu!sdd.hp.com!hpscit.sc.hp.com!cupnews0.cup.hp.com!news1.boi.hp.com!hp-pcd!hpcvra!rnews!hpcvbbs!akcs.joehorn
Newsgroups: comp.sys.hp48
Lines: 104

                   IMPROVED BINARY SEARCH ALGORITHM
                   --------------------------------
                           by Joseph K Horn

While struggling with the problem of inserting an object into a
previously sorted list, I made an unexpected discovery.

The Binary Search algorithm that is taught in college is obsolete, at
least for the HP 48.  There's a shorter and faster way of doing it.

This is a bold thing to say, since Donald Knuth Himself states on page
410 of The Art of Computer Programming, Volume III (Sorting and
Searching) that the following binary search algorithm (which was first
published by him and which I hereafter refer to as Knuth's Algorithm)
is the "best" possible algorithm.  Note that the exit test for
equality is removed, since this is only being used to find the proper
location for the insertion of a new item, and we can therefore assume
that the item will *not* be found.

KNUTH'S BINARY SEARCH-FOR-INSERT ALGORITHM:

(0) We have a list of N items, and we wish to insert T.
(1) Set LO=1 and HI=N.  These are the "brackets" of each bisection.
(2) If HI<LO, stop; insert T at element LO and exit.
(3) Set M=IP((LO+HI)/2).  This is the "midpoint".
(4) Compare T with the Mth item in the list.
(5) If T < the Mth item, set LO=M+1 & go to (2).
(6) Assume T > the Mth item; set HI=M-1 & go to (2).

Notice the +1 in line 5, and the -1 in line 6.  Knuth (and every
computer science professor since the Big Bang) say that this extra
kick helps to speed up the search, but the sad fact is that it's
counterproductive.  By modifying the initial HI and LO values and the
exit test, we can avoid the +1 and the -1 in lines 5 & 6 altogether,
thus tightening up the inner loop.  Since Knuth does not mention this
idea, and since I implemented it in Radio Shack BASIC in the late
1970's since it seemed the obvious way to do it and have been happily
doing it ever since without ever once finding anybody else who does it
or who has even heard of doing it this way, I'll refer to it hereafter
as Horn's Algorithm.  (Antedated references will be greatly
appreciated and acknowledged, etc etc.).

HORN'S BINARY SEARCH-FOR-INSERT ALGORITHM:

(0) We have a list of N items, and we wish to insert T.
(1) Set LO=0 and HI=N+1.  These are the "brackets" of each bisection.
(2) If HI-LO=1, stop; insert T at element HI and exit.
(3) Set M=IP((LO+HI)/2).  This is the "midpoint".
(4) Compare T with the Mth item in the list.
(5) If T < the Mth item, set LO=M & go to (2).
(6) Assume T > the Mth item; set HI=M & go to (2).

Notice the differences in lines 1, 2, 5 and 6.

Both algorithms make EXACTLY the same number of bisections, and go
"up" and "down" in exactly the same sequence, and have the same
result.  But Horn is just a tad shorter and faster than Knuth, at
least in User RPL:

%%HP: T(3)A(D)F(.);
@ LINS1, List Insert by Knuth's Binary Search Algorithm
@ by Joseph K. Horn, 24 May 1993
@ Input: 2: Sorted List, 1: new Object to insert
@ Output: 1: Sorted List containing new Object in correct place
@ BYTES: #F53Ah 137.5
\<< SWAP OBJ\-> DUP 2 + ROLL OVER 5 + 6
  WHILE DUP2 \>=
  REPEAT DUP2 + 2 / IP DUP PICK 5 PICK
    IF >
    THEN SWAP DROP 1 +
    ELSE ROT DROP 1 - SWAP
    END
  END DROP 3 -
ROLLD 1 + \->LIST
\>>

%%HP: T(3)A(D)F(.);
@ LINS2, List Insert by Horn's Binary Search Algorithm
@ by Joseph K. Horn, 24 May 1993
@ Input: 2: Sorted List, 1: new Object to insert
@ Output: 1: Sorted List containing new Object in correct place
@ BYTES: #EEB1h 132.5
\<< SWAP OBJ\-> DUP 2 + ROLL OVER 6 + 5
  WHILE DUP2 - 1 >
  REPEAT DUP2 + 2 / IP DUP PICK 5 PICK
    IF >
    THEN SWAP DROP
    ELSE ROT DROP SWAP
    END
  END DROP 4 -
ROLLD 1 + \->LIST
\>>

Example of either program in use:
INPUT:  { 2 4 6 8 10 }  5
OUTPUT: { 2 4 5 6 8 10 }

Although the size and speed improvement is small in User RPL, I
suspect that the improvement would be more marked in System RPL, but
testing that hypothesis is left as an exercise for the student.  ;-)

-Joseph K. Horn-   -Peripheral Vision, Ltd.-
akcs.joehorn@hpcvbbs.cv.hp.com
Disclaimer: I don't work for HP, EduCALC, or on weekends.


