📄 dlist.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 + -