Click here to Skip to main content
Licence 
First Posted 2 Jun 2005
Views 14,569
Bookmarked 12 times

Templates for sorted and unsorted lists

By | 2 Jun 2005 | Article
Templates for sorted and unsorted lists.

Introduction

I believe anyone who programmed for a while would have encountered the need for lists, sorted or unsorted, for different types of objects. Anyway, I did, and I wanted an easy way to have lists without the need of writing basically the same code for each type. Although there are the vector and map templates, I found their use a bit too demanding for me, and I had set my mind to write my own code, which so far served me very well.

Template's Definition

The template class does the simple act of taking care of memory allocation, while the derived sorted one adds logarithmic sorting functionality as well. The list template has three members. m_list which is a pointer to the list of objects, size and max. The size variable is the number of active places in the list, and the max variable is the actual size of allocated places in the list. Sorted lists have another public member bMultiple which allows them to have multiple objects in case the comparison method indicates they are equal.

Definition:

template <class T, class F=T, class S=Int16> 
class AIList {

T stands for the list's type, F for the type of object passed for the Add method for creating new T objects, and S is the type for the size and max variables. In the sorted list for pointers, the object has to have an int Compare(F&) method, and for non pointers an overloaded int operator -(F&).

Methods

Here are the methods of the base class AIList:

// Allocation functions 
void Attach (AIList <T, F, S>& p) 
    { RemoveAll(true); size = p.GetSize(); 
    max = p.GetMax(); m_list = p.Detach(); }
void Attach (T* p, S n)
    { if (m_list) delete [] m_list; size = max = n; m_list = p; }
void SetMinSize (S n) { if (max < n) GrowBy (n - max); }
void GrowBy (S n);
void AddActive (S n) 
    { if (size + n > max) { GrowBy (size + n - max); size = max; } 
      else size +=n; }
void Add (F& obj, S nPos = -1);
void Add (AIList <T, F, S>& obj, S nPos);
AIList <T, F, S>& operator += (AIList <T, F, S>& p);
AIList <T, F, S>& operator = (AIList <T, F, S>& p) 
    { RemoveAll(); return *this += p; }
// Dellocation functions 
T* Detach () { T* tmp = m_list; size = max = 0; m_list = 0; return tmp; } 
void RemoveAt (S pos, T* obj = 0);
void RemoveAll (bool bReset = true) 
    { if (max && bReset) 
      { delete []m_list; m_list = 0; max = 0; } 
      size = 0; }
void Remove (T& p, T* obj = 0) { RemoveAt (Find (p), obj); }
void RemoveLast (T* obj = 0) { RemoveAt (size-1, obj); }
// for list of pointers only 
void FreeList (bool bReset = true) 
    { for (S i=size ; i-- ; ) 
      { if (m_list[i]) delete m_list[i]; } 
      RemoveAll(bReset); }
 
// Access functions 
const T& GetLast() const { ASSERT (size); return m_list[size-1]; }
const T& operator [] (S pos) const 
    { ASSERT (!pos || pos < size); return m_list[pos]; }
T& GetLast() { ASSERT (size); return m_list[size-1]; }
T& operator [] (S pos) { ASSERT (!pos || pos < size); return m_list[pos]; }
S Find (T& obj, S nStart = 0) const { ... }
bool operator == (AIList <T, F, S>& p) const;
void FitToSize();

Example

class Word {
    char* m_desc;
public:
    Word() { m_desc = 0; }
    Word(char* p) { m_desc = strdup(p); }
    ~Word() { if (m_desc) delete m_desc; }
    int Compare(char* p) { return stricmp (m_desc, p); }
    const char* GetDesc() { return m_desc; }
};
void main() {
   AISortedList<Word, char*> words; 
   char* pp = "foo";
   words.Add (pp);
   ...
   // since it's a pointers list
   words.FreeList();
}

Remarks

Three things that are worth noting are:

  1. The algorithm for memory allocation in the Add and RemoveAt methods, which might be changed to a different one:
    template<class T, class F, class S>
    void AIList<T, F, S>::Add (F& obj, S nPos) {
        ...
        if (size == max) {
        ==>    max += max/2 + 1;
            tmp = new T [max];
            for (i=0 ; i<nPos ; i++) tmp[i] = m_list[i];
        } else tmp = m_list;
        ...
    }
    template<class T, class F, class S>
    void AIList<T, F, S>::RemoveAt (S pos, T* obj) {
        ...
        ==> if (size < max / 2) {
        ==>    tmp = new T [size];
            for (i=0 ; i<pos ; i++) tmp[i] = m_list[i];
            max = size;
        } else tmp = m_list;
        ...
    }
  2. The int type for the comparison results in the FindHelper method for the sorted lists. The problem with the int type is that in float or double types the comparison is of course not valid if the difference is less than 1.
    template <class T, class F, class S>
    bool AISortedList2<T, F, S>::FindHelper (F& p, S& pos) const {
        int r; ... 
        r = m_list[pos] - p; ... 
    }
  3. There are probably some places for improvement.

Conclusion

I hope you find good use for this code. Any remarks or suggestions are more than welcome.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

arui69

Web Developer

United States United States

Member

I started writing code at the respectable age of 17 (a bit late for some Smile | :) ). I have a BA in cognitive science and dream of real AI, which a deterministic person like myself believes in its existance and thats of the Matrix...

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralAmerican colloquialisms PinmemberJim Crafton7:51 2 Jun '05  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 2 Jun 2005
Article Copyright 2005 by arui69
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid