THIS FILE ILLUSTRATES HOW CODE FOR LINKED STRUCTURES LOOKS IN THREE DIFFERENT IMPLEMENTATIONS. THE FEW DIFFERENCES BETWEEN THE TWO VERSIONS ARE *CAPITALIZED* TO MAKE THEM EASIER TO SPOT. (* ################################################## *) (* ################################################## *) IMPLEMENTATION #1: Search and Insertion in an ordered linked list implemented with Pascal records for nodes and PASCAL POINTERS inside the nodes FOR LINKS: (* ################################################## *) type infoType = char ; LINKTYPE = ^NODETYPE ; nodeType = record data : infoType ; next : linkType end ; (* ################################################## *) var theListPtr : linkType ; (* external pointer to list *) theData : infoType ; (* ################################################## *) (* foundKey returns true if list contains a node having the search key as data field, else false. If foundKey returns true, curntPtr points to first node containing key. If not foundKey, and the list has any nodes with data larger than search key, then curntPtr points to the first such node. If all nodes in list have data smaller than search key, then curntPtr returns with value NIL. PrevPtr returns pointing to the node just before current, if it exists, else is NIL. *) (* ################################################## *) procedure FindKey ( key : infoType; listPtr : linkType; var prevPtr, curntPtr : linkType; var foundKey : boolean ) ; var atEnd, foundLarger : boolean ; begin (* procedure FindKey *) foundKey := false ; foundLarger := false ; prevPtr := NIL ; curntPtr := listPtr ; repeat atEnd := (curntPtr = NIL) ; if not atEnd then if CURNTPTR^.DATA < key then begin prevPtr := curntPtr ; curntPtr := CURNTPTR^.NEXT end else begin foundKey := (CURNTPTR^.DATA = key) ; foundLarger := (CURNTPTR^.DATA > key) end until foundKey or foundLarger or atEnd ; end ; (* procedure FindKey *) (* ################################################## *) procedure Insert (newData : infotype ; var listPtr : linkType) ; var prevPtrI, curntPtrI, ptrToNew : linkType ; foundKey : boolean ; begin (* procedure Insert *) NEW(PTRTONEW) ; PTRTONEW^.DATA := newData ; FindKey ( newData, listPtr, prevPtrI, curntPtrI, foundKey) PTRTONEW^.NEXT := curntPtrI ; (* New element goes before current.*) if prevPtrI = NIL (* If we are adding first list elt *) then listPtr := ptrToNew (* then update the list pointer *) else PREVPTRI^.NEXT := ptrToNew (* else make the previous node *) end ; (* procedure Insert *) (* point to the new node *) (* ################################################## *) (* ################################################## *) IMPLEMENTATION #2: Search and Insertion in an ordered linked list implemented with an ARRAY OF Pascal records for nodes and INTEGERS FOR LINKS. Here we put the pointers in the nodes. (* ################################################## *) CONST NULL = 0 ; (* ################################################## *) type infoType = char ; LINKTYPE = INTEGER ; nodeType = record data : infoType ; next : linkType end ; (* ################################################## *) var theListPtr : linkType ; (* external pointer to list *) NODES : ARRAY [1..MAX] OF NODETYPE theData : infoType ; (* ################################################## *) (* foundKey returns true if list contains a node having the search key as data field, else false. If foundKey returns true, curntPtr points to first node containing key. If not foundKey, and the list has any nodes with data larger than search key, then curntPtr points to the first such node. If all nodes in list have data smaller than search key, then curntPtr returns with value NULL. PrevPtr returns pointing to the node just before current, if it exists, else is NULL. *) (* ################################################## *) procedure FindKey ( key : infoType; listPtr : linkType; var prevPtr, curntPtr : linkType; var foundKey : boolean ) ; var atEnd, foundLarger : boolean ; begin (* procedure FindKey *) foundKey := false ; foundLarger := false ; prevPtr := NULL ; curntPtr := listPtr ; repeat atEnd := (curntPtr = NULL) ; if not atEnd then if NODES[CURNTPTR].DATA < key then begin prevPtr := curntPtr ; curntPtr := NODES[CURNTPTR].NEXT end else begin foundKey := (NODES[CURNTPTR].DATA = key) ; foundLarger := (NODES[CURNTPTR].DATA > key) end until foundKey or foundLarger or atEnd ; end ; (* procedure FindKey *) (* ################################################## *) procedure Insert (newData : infotype ; var listPtr : linkType) ; var prevPtrI, curntPtrI, ptrToNew : linkType ; foundKey : boolean ; begin (* procedure Insert *) GETNODE(PTRTONEW) ; (* this procedure is assumed to exist *) NODES[PTRTONEW].DATA := newData ; FindKey ( newData, listPtr, prevPtrI, curntPtrI, foundKey) NODES[PTRTONEW].NEXT:= curntPtrI; (* New element goes beforecurrent. *) if prevPtrI = NULL (* If we are adding first list elt *) then listPtr := ptrToNew (* then update the list pointer *) else NODES[PREVPTRI].NEXT := ptrToNew (* else make the previous node *) end ; (* procedure Insert *) (* point to the new node *) FindKey ( newData, listPtr, prevPtrI, curntPtrI, foundKey) (* ################################################## *) (* ################################################## *) IMPLEMENTATION #3: Search and Insertion in an ordered linked list implemented with AN ARRAY OF Pascal records for nodes and INTEGERS FOR LINKS. Here we put the links in a separate array. (* ################################################## *) CONST NULL = 0 ; (* ################################################## *) type infoType = char ; LINKTYPE = INTEGER ; NODETYPE = RECORD DATA : INFOTYPE ; END ; (* ################################################## *) var NODES : ARRAY [1..MAX] OF NODETYPE NEXT : ARRAY [0..MAX] OF NODETYPE theData : infoType ; (* ################################################## *) (* foundKey returns true if list contains a node having the search key as data field, else false. If foundKey returns true, curntPtr points to first node containing key. If not foundKey, and the list has any nodes with data larger than search key, then curntPtr points to the first such node. If all nodes in list have data smaller than search key, then curntPtr returns with value NULL. PrevPtr returns pointing to the node just before current, if it exists, else is NULL. *) (* ################################################## *) procedure FindKey ( key : infoType; listPtr : linkType; var prevPtr, curntPtr : linkType; var foundKey : boolean ) ; var atEnd, foundLarger : boolean ; begin (* procedure FindKey *) foundKey := false ; foundLarger := false ; prevPtr := NULL ; curntPtr := listPtr ; repeat atEnd := (curntPtr = NULL) ; if not atEnd then if NODES[CURNTPTR].DATA < key then begin prevPtr := curntPtr ; curntPtr := NEXT[CURNTPTR] end else begin foundKey := (NODES[CURNTPTR].DATA = key) ; foundLarger := (NODES[CURNTPTR].DATA > key) end until foundKey or foundLarger or atEnd ; end ; (* procedure FindKey *) (* ################################################## *) (* When Insert is called, use NEXT[0] as the list pointer. In other words the call to Insert should be something like: Insert ('t', NEXT[0], prevPtr, curntPtr, ptrToNew, foundKey) *) procedure Insert (newData : infotype ; var listPtr : linkType) ; var prevPtrI, curntPtrI, ptrToNew : linkType ; foundKey : boolean ; begin (* procedure Insert *) GETNODE(PTRTONEW) ; (* this procedure is assumed to exist *) NODES[PTRTONEW].DATA := newData ; FindKey ( newData, listPtr, prevPtrI, curntPtrI, foundKey) NEXT[PTRTONEW] := curntPtrI; (* New element goes before current.*) if prevPtrI = NULL (* If we are adding first list elt *) then listPtr := ptrToNew (* then update the list pointer *) else NEXT[PREVPTRI] := ptrToNew (* else make the previous node *) end ; (* procedure Insert *) (* point to the new node *) (* ################################################## *)