2.4. Searching a Linked List

To support:

class BidderCollection {
    ⋮
  Position findBidder (std::string name) const;
  // Returns the position where a bidde mathcing the given
  // name can be found, or null if no bidder with that name exists.

we do a traversal but stop early if we find what we are looking for.

findBidder

/**
 * Find the index of the bidder with the given name. If no such bidder exists,
 * return null.
 */
BidderCollection::Position BidderCollection::findBidder 
   (std::string name) const
{
  for (Position current = list.first; current != NULL; 
       current = current->next) 
    {
      if (name == current->data.getName())
        return current;
    }
  return NULL;
}

Searching Linked Lists

As a general utility, we might try to provide:

template <typename Data>
struct LListHeader {

  LListNode<Data>* first;
    ⋮
  // Search for a value. Returns null if not found
  LListNode<Data>* find (const Data& value) const;

  // Search an ordered list for a value. Returns null if not found
  LListNode<Data>* findOrdered (const Data& value) const;

Searching Unordered Linked Lists

  // Search for a value. Returns null if not found
template <typename Data>
LListNode<Data>* LListHeader<Data>::find 
   (const Data& value) const
{
  LListNode<Data>* current = first;
  while (current != NULL && value != current->data)
    current = current->next;
  return current;
}

Searching Ordered Linked Lists

  // Search an ordered list for a value. Returns null if not found
template <typename Data>
LListNode<Data>* LListHeader<Data>::findOrdered 
  (const Data& value) const
{
  LListNode<Data>* current = first;
  while (current != NULL && value > current->data)
    current = current->next;
  if (current != NULL && value == current->data)
    return current;
  else
    return NULL;
}

findBidder (alternate)

/**
 * Find the index of the bidder with the given name. If no such bidder exists,
 * return null.
 */
BidderCollection::Position BidderCollection::findBidder 
   (std::string name) const
{
  Bidder searchFor (name, 0.0);
  return list.find (searchFor);
}

(works only because

bool Bidder::operator== (const Bidder& b) const
{
  return name == b.name;
}


bool Bidder::operator< (const Bidder& b) const
{
  if (name < b.name)
    return true;
  else
    return false;
}

compare only by name).

Walking Two Lists at Once

Although not really a search, the relational operator code is similar, in that we do a traversal with a possible early exit. But now we have two walk two lists:

  // Comparison operators
bool BidderCollection::operator== (const BidderCollection& bc) const
{
  if (size == bc.size)
    {
      Position current = list.first;
      Position bcurrent = bc.list.first;
      while (current != NULL)
        {
          if (!(current->data == bcurrent->data))
            return false;
          current = current->next;
          bcurrent = bcurrent->next;
        }
      return true;
    }
  else
    return false;
}