⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlist.h

📁 数据挖掘经典的hierarchial clustering algorithm
💻 H
字号:
=====================================================================
  DEVise Data Visualization Software
  (c) Copyright 1992-1995
  By the DEVise Development Group
  Madison, Wisconsin
  All Rights Reserved.
  ========================================================================

  Under no circumstances is this software to be copied, distributed,
  or altered in any way without prior permission from the DEVise
  Development Group.
*/

/*
  $Id: DList.h,v 1.9 1996/11/26 16:47:42 ssl Exp $

  $Log: DList.h,v $
  Revision 1.9  1996/11/26 16:47:42  ssl
  Added support for Stacked Opaque and Transparent views

  Revision 1.8  1996/08/04 20:58:52  beyer
  Insertion with iterators is now ok.

  Revision 1.7  1996/07/25 14:33:48  guangshu
  Added member function InsertOrderly

  Revision 1.6  1996/04/16 20:06:54  jussi
  Replaced assert() calls with DOASSERT macro.

  Revision 1.5  1996/04/09 18:06:34  jussi
  Added error checking.

  Revision 1.4  1996/04/08 22:13:18  jussi
  Added assertions along the way.

  Revision 1.3  1995/12/28 18:45:12  jussi
  Added copyright notice and made small fixes to remove compiler
  warnings.

  Revision 1.2  1995/09/05 21:12:37  jussi
  Added/updated CVS header.
*/

#ifndef DList_h
#define DList_h

#include "Exit.h"

const int MaxIterators = 5;             /* max # of concurrent iterators */

#define DefineDList(listName, valType)\
class listName {\
\
        struct ListElement {\
                ListElement *next, *prev;\
                valType val;\
        };\
\
        struct IteratorData {\
                ListElement *current;   /* == NULL if not used */\
                int backwards; /* TRUE if iterate backwards */\
        };\
\
public:\
        listName();\
        ~listName();\
\
        int Size();\
\
        void Insert(valType v);\
        void InsertOrderly(valType v, int order);\
        void Append(valType v);\
\
        /* Return true if v is in the list */\
        int Find(valType v);\
\
        /* Delete v from list. Return true if v is found */\
        int Delete(valType v);\
\
        /* Return the first element */\
        valType GetFirst();\
\
        /* Return the last element */\
        valType GetLast();\
\
        /* swap elements a and b */\
        void Swap(valType a, valType b);\
\
        /* iterator for the list. This implementation supports\
        multiple iterators, and also  supports \
        Deletecurrent(), which deletes the current element being looked at. \
        Note:  DeleteCurrent() is an error when more than 1 iterator is in \
        effect.\
        */\
\
        /* Init and return index of iterator */\
        int InitIterator(int backwards=0);\
\
        /* Init iterator to return the last N records */\
        int InitIteratorLastN(int n=1);\
        int More(int index);\
        valType Next(int index); \
        void DeleteCurrent(int index) ;\
        void InsertAfterCurrent(int index, valType v); \
        void InsertBeforeCurrent(int index, valType v); \
        void DoneIterator(int index);\
        void DeleteAll();\
        void PrintIterators();\
\
protected:\
        /* insert node2 after node 1 */\
        void _Insert(ListElement *node1, ListElement *node2);\
\
        /* delete node */\
        void _DListDelete(ListElement *node);\
\
private:\
        void ClearIterators();\
        ListElement *_head;\
        int _size;              /* size of the list */\
\
        IteratorData _iterators[MaxIterators];\
        int _numIterators ;\
};

#define ImplementDList(listName,valType)\
\
listName::listName(){\
        _head = new ListElement;\
        _head->next = _head->prev = _head;\
        _size=0;\
        ClearIterators();\
\
}\
\
listName::~listName() { DeleteAll(); delete _head; }\
\
int listName::Size() { return _size; }\
\
void listName::Insert(valType v){\
        ListElement *node = new ListElement;\
        node->val = v;\
        _Insert(_head, node);\
}\
\
/* insert v in increasing order if order = 1, in decreasing order if order = 0 */\
void listName::InsertOrderly(valType v, int order){\
        ListElement *new_node = new ListElement;\
        ListElement *node;\
        new_node->val = v;\
        if(order == 1) {\
            for (node = this->_head->next; v >= node->val && node != this->_head; node = node->next){}\
        } else if(order == 0) {\
            for (node = this->_head->next; v <= node->val && node != this->_head; node = node->next){}\
        } else {\
            DOASSERT(0, "Invalid order");\
            return;\
        }\
        _Insert(node->prev, new_node);\
}\
\
void listName::Append(valType v){\
        ListElement *node = new ListElement;\
        node->val = v;\
        _Insert(_head->prev, node);\
}\
\
/* Return the first element */\
valType listName::GetFirst() {\
        DOASSERT(_head->next != _head, "Empty list");\
        return _head->next->val;\
}\
\
/* Return the last element */\
valType listName::GetLast() {\
        DOASSERT(_head->prev != _head, "Empty list");\
        return _head->prev->val;\
}\
\
void listName::Swap(valType val1, valType val2) {\
        ListElement *node;\
        ListElement *node1=NULL;\
        ListElement *node2=NULL;\
        for (node = this->_head->next; node != this->_head; node = node->next){\
                if (node->val == val1) {\
                        node1 = node;\
                } else if (node->val == val2) {\
                        node2 = node;\
                }\
        }\
        DOASSERT(node1 && node2, "Empty lists");\
        node1->val = val2;\
        node2->val = val1;\
}\
\
\
/* Init and return index of iterator */\
int listName::InitIterator(int backwards) {\
        /* find an empty slot in the array of active iterators */\
        for(int i = 0; i < MaxIterators; i++) {\
                if (_iterators[i].current == NULL){\
                        /* found one */\
                        _iterators[i].backwards = backwards;\
                        if (backwards)\
                                _iterators[i].current = _head->prev;\
                        else\
                                _iterators[i].current = _head->next; \
                        _numIterators++;\
                        return i;\
                }\
        }\
        DOASSERT(0, "No more space for iterators");\
        return -1; /* to keep compiler happy */\
}\
\
/* DEBUGGING FUNCTION : Print Iterators */ \
void listName::PrintIterators() { \
    printf("printing active iterators (%d)",_numIterators );\
    for (int i = 0; i < MaxIterators; i++) { \
        if (_iterators[i].current != NULL) {\
           printf("iterator open %p\n", _iterators[i].current);\
        }\
    }\
}\
\
/* Init iterator to return the last N records */\
int listName::InitIteratorLastN(int n){\
        DOASSERT(n >= 1, "Invalid parameter");\
        /* find an empty slot in the array of active iterators */\
        for(int i = 0; i < MaxIterators; i++) {\
                if (_iterators[i].current == NULL){\
                        /* found one */\
                        _iterators[i].backwards = 0;\
                        if (Size() >= n){\
                                /* more than enough entries. Scan backwards n records */\
                                _iterators[i].current = _head->prev;\
                                for (int j=1; j < n; j++)\
                                        _iterators[i].current = _iterators[i].current->prev;\
                        }\
                        else\
                                _iterators[i].current = _head->next; \
                        _numIterators++;\
                        return i;\
                }\
        }\
        DOASSERT(0, "No more space for iterators");\
        return -1; /* to keep compiler happy */\
}\
\
int listName::More(int index) {\
        DOASSERT(index >= 0 && index < MaxIterators, "Invalid iterator");\
        return _iterators[index].current != _head;\
}\
\
valType listName::Next(int index) { \
        DOASSERT(index >= 0 && index < MaxIterators, "Invalid iterator");\
        IteratorData *iData = &_iterators[index];\
        valType v = iData->current->val;\
        if (iData->backwards)\
                iData->current = iData->current->prev;\
        else iData->current = iData->current->next; \
        return v; \
}\
\
void listName::DeleteCurrent(int index) {\
        DOASSERT(index >= 0 && index < MaxIterators, "Invalid iterator");\
        DOASSERT(_numIterators <= 1, "Cannot delete with iterator");\
        if (_iterators[index].backwards)\
                _DListDelete(_iterators[index].current->next);\
        else\
                _DListDelete(_iterators[index].current->prev);\
}\
void listName::InsertAfterCurrent(int index, valType v){ \
        DOASSERT(index >= 0 && index < MaxIterators, "Invalid iterator");\
        IteratorData *iData = &_iterators[index];\
        ListElement *node = new ListElement;\
        node->val = v;\
        if (iData->backwards) \
                _Insert(iData->current, node);\
        else \
                _Insert(iData->current->prev, node);\
} \
void listName::InsertBeforeCurrent(int index, valType v){ \
        DOASSERT(index >= 0 && index < MaxIterators, "Invalid iterator");\
        IteratorData *iData = &_iterators[index];\
        ListElement *node = new ListElement;\
        node->val = v;\
        if (iData->backwards) \
                _Insert(iData->current->prev, node);\
        else \
                _Insert(iData->current->prev->prev, node);\
} \
void listName::DoneIterator(int index){\
        DOASSERT(index >= 0 && index < MaxIterators\
                 && _iterators[index].current != NULL, "Invalid iterator");\
        _iterators[index].current = NULL;\
        --_numIterators;\
        DOASSERT(_numIterators >= 0, "Invalid iterator count");\
}\
\
/* insert node2 after node 1 */\
void listName::_Insert(ListElement *node1, ListElement*node2){\
        node2->next = node1->next;\
        node2->prev = node1;\
        node1->next->prev = node2;\
        node1->next = node2;\
        _size++;\
}\
\
/* delete node */\
void listName::_DListDelete(ListElement *node){\
        DOASSERT(node != _head, "Cannot delete head of list");\
        node->next->prev = node->prev;\
        node->prev->next = node->next;\
        delete node;\
        _size--;\
}\
\
void listName::ClearIterators(){\
        for(int i = 0; i < MaxIterators; i++)\
                _iterators[i].current = NULL;\
        _numIterators = 0;\
}\
\
int listName::Find(valType v) {\
        ListElement *node;\
        for (node = this->_head->next; node != this->_head; node = node->next){\
                if (node->val == v){\
                        return 1; /* true */\
                }\
        }\
        return 0;       /* false */\
}\
\
int listName::Delete(valType v){\
        DOASSERT(!_numIterators, "Cannot delete with iterator");\
        ListElement *node;\
        for (node = this->_head->next; node != this->_head; node = node->next){\
                if (node->val == v){\
                        _DListDelete(node);\
                        return 1; /* true */\
                }\
        }\
        return 0;       /* false */\
}\
\
void listName::DeleteAll(){\
        while (_head->next != _head)\
                _DListDelete(_head->next);\
        _size = 0;\
}\

/* define a void list */
DefineDList(VoidList, void *)

/* template to convert pointer list to use VoidList.
valType must be a pointer. */
#define DefinePtrDList(listName, valType)\
class listName {\
public:\
        int Size() { return _voidList.Size(); }\
\
        void Insert(valType v) { _voidList.Insert((void *)v);}\
        void Append(valType v) { _voidList.Append((void *)v);}\
\
        /* Return true if v is in the list */\
        int Find(valType v) { return _voidList.Find((void *)v);}\
\
        /* Delete v from list. Return true if v is found */\
        int Delete(valType v) { return _voidList.Delete((void *)v); }\
\
        /* Return the first element */\
        valType GetFirst() { return (valType)_voidList.GetFirst();} \
\
        /* Return the last element */\
        valType GetLast() { return (valType)_voidList.GetLast();}\
\
        /* Swap two list elements */\
        void Swap(valType val1, valType val2) { \
                _voidList.Swap((void *)val1,(void *)val2);\
        }\
\
        /* Init and return index of iterator */\
        int InitIterator(int backwards=0) {\
                return _voidList.InitIterator(backwards);}\
\
        /* Init iterator to return the last N records */\
        int InitIteratorLastN(int n=1){ return _voidList.InitIteratorLastN(n);}\
        int More(int index){return _voidList.More(index);}\
        valType Next(int index){ return (valType)_voidList.Next(index);} \
        void DeleteCurrent(int index){_voidList.DeleteCurrent(index);} \
        void InsertAfterCurrent(int indx, valType v) { \
                _voidList.InsertAfterCurrent(indx,v);\
        }\
        void InsertBeforeCurrent(int indx, valType v) {\
                _voidList.InsertBeforeCurrent(indx,v);\
        }\
        void DoneIterator(int index){_voidList.DoneIterator(index);}\
        void PrintIterators() {_voidList.PrintIterators();}\
private:\
        VoidList _voidList; \
};

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -