📄 oopiclist.h
字号:
#ifndef __List_h#define __List_h#if defined(__GNUC__) || defined(__BORLANDC__) || defined(_MSC_VER) || defined(__KCC) || defined(_CRAYT3E) || defined(_AIX)/*====================================================================oopicList.H0.9 (PeterM, 08-93) Original List and Stack classes in G++.0.961 (PeterM, JohnV, 08-24-93) Replace Borland list containers with vanilla C++ template lists in List.h0.964 (JohnV, 09-28-93) Add ListIter::delete() and supporting data.0.97 (JamesA 12-30-93) Add restart() to ListIter0.971 (JamesA 02-05-94) Add putAt(), getAt(), find() to List, itemName to ListItem.0.975 (JamesA 03-12-94) Add removeItem() to List. (HadonN 06-16-94) Add removeAll(), fix(?) removeItem() (HadonN 09-19-94) fix(!) removeItem()0.976 (Hadon 10-20-94) removed putAt(), getAt(), find() from List0.977 (Hadon 10-28-94) fix operator=(), (call removeAll())0.978 (JohnV 06-30-95) add deleteAll() to delete all data and remove all items.0.979 (JohnV 01-11-96) incorporate undocumented additions (from Acquah?)1.001 (JohnV 02-29-96) renamed N_items() -> nItems().====================================================================*/#include <string.h>#if defined(__BORLANDC__)#include <alloc.h>#endif#if defined(_MSC_VER)#include <malloc.h>#endif#include <stdlib.h>template <class Type> class oopicListItem{public: oopicListItem(Type *newitem, oopicListItem<Type> *nxt, const char* key = "") // jbha {data=newitem; next=nxt; itemName = strdup(key);} ~oopicListItem() { if (itemName) free(itemName); itemName = NULL; next = NULL; data = NULL; }/* ~ListItem() { free(itemName); } deleteData() {delete data; data = NULL; free(itemName); itemName = NULL;} (commented out 01-11-96 JohnV)*/ char* itemName; // jbha oopicListItem<Type> *next; Type *data;};template <class Type> class oopicListIter;template <class Type> class oopicList{public: int nitems; oopicListItem<Type> *head; oopicList() {head=0; nitems=0;} oopicList(oopicList<Type> &other) { head=0;nitems=0; *this=other; } ~oopicList() {// JRC: Seems poorly defined as to whether this is a handoff // deleteAll(); removeAll(); } void removeItem( Type *anItem); void removeAll(); void deleteAll();/** Add a new item * this is a handoff. */ void add(Type *newitem); void addToEnd(Type *newitem); // expensive walk-the-list-to-end-and-add oopicList<Type>& operator=(oopicList<Type> &other) { //Not a terribly efficient routine. //first copy of list is reversed. //reversed_list goes out of scope and is deleted. oopicListIter<Type> walk(other); oopicList<Type> reversed_list; removeAll(); while(!walk.Done()) { reversed_list.add(walk.current()); walk++; } oopicListIter<Type> walk2(reversed_list); while(!walk2.Done()) { add(walk2.current()); walk2++; } return *this; }; Type * pop(void) { if(head) { Type* retval=head->data; oopicListItem<Type> *to_delete=head; head = head->next; delete to_delete; nitems--; return retval; } else return 0; } int isEmpty() {return (head==0);} void push(Type *newitem) { add(newitem); }; int nItems() {return nitems;};};template <class Type> void oopicList<Type>::add(Type *newitem){ oopicListItem<Type> *New = new oopicListItem<Type>(newitem, head); nitems++; head = New;}// Add an element to the end of the list. Requires a list traversal.template <class Type> void oopicList<Type>::addToEnd(Type *newitem){ oopicListItem<Type> *New = new oopicListItem<Type>(newitem,NULL); oopicListItem<Type> *walk; nitems++; if(head==NULL) { head = New; return; } // find the end of the list for( walk=head; walk->next!=NULL; walk=walk->next ); walk->next = New;}template <class Type>void oopicList<Type>::removeItem( Type *anItem )// use when you need to find the item first, else use version in oopicListIter{ oopicListItem<Type> *prevPtr, *currentPtr; if (head == NULL) { return; } else if (head->data == anItem) { currentPtr = head->next; delete head; head = currentPtr; nitems--; } else { prevPtr = head; currentPtr = prevPtr->next; while( !(currentPtr == NULL) ) { if ( currentPtr->data == anItem ) { prevPtr->next = currentPtr->next; delete currentPtr; currentPtr = prevPtr->next; nitems--; } else { prevPtr = currentPtr; currentPtr = currentPtr->next; } } }}// removeAll: removes all list elements, but NOT the data!template <class Type>void oopicList<Type>::removeAll(){ oopicListItem<Type> *next; while (head) { next = head->next; delete head; head = next; } nitems = 0;}// deleteAll: removes all list elements AND datatemplate <class Type>void oopicList<Type>::deleteAll(){ oopicListItem<Type> *next; while ( head ) { next = head->next; delete head->data; delete head; head = next; } nitems = 0;}/* Acquah's version: template <class Type> void oopicList<Type>::deleteAllData() { ListItem<Type> *next, *current; current = head; // necc because deleteData() sometimes head = NULL; // ... (eventually) calls removeItem() while ( current ) { next = (*current).next; current->deleteData(); delete current; current = next; } nitems = 0; }*/////////////////////////////////////////////////////////////////////////////////template <class Type> class oopicListIter{public: oopicListItem<Type>* currentPtr; oopicListItem<Type>* previousPtr; oopicList<Type>* theList; oopicListIter(){} // empty constructor, must be used with restart oopicListIter(oopicList<Type>& aList) {theList=&aList; restart();}; void restart() {previousPtr = currentPtr = theList->head;}; void restart(oopicList<Type>& aList) {theList=&aList; restart();}; void restart(Type& aGroup); Type* data() {if (currentPtr) return currentPtr->data; else return NULL;}; Type* current() {return data();}; Type* operator () () {return data();}; void operator++(int) {if (currentPtr) {previousPtr = currentPtr; currentPtr = currentPtr->next;} else restart();}; int Done() {return currentPtr==NULL;}; int isEmpty() {return !(theList->head==0);}; void deleteCurrent();};// This function removes an item from the list. Might be cleaner// if it is inside oopicList<Type>, but do not want order n search// for element.template <class Type>void oopicListIter<Type>::deleteCurrent(){ if (currentPtr == NULL) return; // bail out if empty or at end // if at head of list, point head to next item if (currentPtr == theList->head) { theList->head = currentPtr->next; previousPtr = NULL; } else previousPtr->next = currentPtr->next; delete current(); // delete the data delete currentPtr; // delete the list item currentPtr = previousPtr; theList->nitems--;}#else // following is for compilers other than __GNUC__ and __BORLANDC__ #include <string.h>#include <stdlib.h>template <class Type> class oopicListItem{public: oopicListItem(Type *newitem, oopicListItem<Type> *nxt, const char* key = "") // jbha {data=newitem; next=nxt; itemName = strdup(key);} ~oopicListItem() {free(itemName); itemName = NULL; next = NULL; data = NULL;}/* ~ListItem() { free(itemName); } deleteData() {delete data; data = NULL; free(itemName); itemName = NULL;} (commented out 01-11-96 JohnV)*/ char* itemName; // jbha oopicListItem<Type> *next; Type *data;};template <class Type> class oopicListIter;template <class Type> class oopicList{public: int nitems; oopicListItem<Type> *head; oopicList() {head=0; nitems=0;} oopicList(oopicList<Type> &other) { head=0;nitems=0; *this=other; } ~oopicList() {removeAll();} oopicList<Type>& operator=(oopicList<Type> &other) { //Not a terribly efficient routine. //first copy of list is reversed. //reversed_list goes out of scope and is deleted. oopicListIter<Type> walk(other); oopicList<Type> reversed_list; removeAll(); while(!walk.Done()) { reversed_list.add(walk.current()); walk++; } oopicListIter<Type> walk2(reversed_list); while(!walk2.Done()) { add(walk2.current()); walk2++; } return *this; }; Type * pop(void) { if(head) { Type* retval=head->data; oopicListItem<Type> *to_delete=head; head = head->next; delete to_delete; nitems--; return retval; } else return 0; } int isEmpty() {return (head==0);} void push(Type *newitem) { add(newitem); }; int nItems() {return nitems;}; void add(Type *newitem) { oopicListItem<Type> *New = new oopicListItem<Type>(newitem, head); nitems++; head = New; } void removeItem( Type *anItem ) // use when you need to find the item first, else use version in oopicListIter { oopicListItem<Type> *prevPtr, *currentPtr; if (head == NULL) { return; } else if (head->data == anItem) { currentPtr = head->next; delete head; head = currentPtr; nitems--; } else { prevPtr = head; currentPtr = prevPtr->next; while( !(currentPtr == NULL) ) { if ( currentPtr->data == anItem ) { prevPtr->next = currentPtr->next; delete currentPtr; currentPtr = prevPtr->next; nitems--; } else { prevPtr = currentPtr; currentPtr = currentPtr->next; } } } }// removeAll: removes all list elements, but NOT the data! void removeAll() { oopicListItem<Type> *next; while (head) { next = head->next; delete head; head = next; } nitems = 0; }// deleteAll: removes all list elements AND data void deleteAll() { oopicListItem<Type> *next; while ( head ) { next = head->next; delete head->data; delete head; head = next; } nitems = 0; }};/* Acquah's version: template <class Type> void oopicList<Type>::deleteAllData() { ListItem<Type> *next, *current; current = head; // necc because deleteData() sometimes head = NULL; // ... (eventually) calls removeItem() while ( current ) { next = (*current).next; current->deleteData(); delete current; current = next; } nitems = 0; }*/////////////////////////////////////////////////////////////////////////////////template <class Type> class oopicListIter{public: oopicListItem<Type>* currentPtr; oopicListItem<Type>* previousPtr; oopicList<Type>* theList; oopicListIter(){} // empty constructor, must be used with restart oopicListIter(oopicList<Type>& aList) {theList=&aList; restart();}; void restart() {previousPtr = currentPtr = theList->head;}; void restart(oopicList<Type>& aList) {theList=&aList; restart();}; void restart(Type& aGroup); Type* data() {if (currentPtr) return currentPtr->data; else return NULL;}; Type* current() {return data();}; Type* operator () () {return data();}; void operator++(int) {if (currentPtr) {previousPtr = currentPtr; currentPtr = currentPtr->next;} else restart();}; int Done() {return currentPtr==NULL;}; int isEmpty() {return !(theList->head==0);};// This function removes an item from the list. Might be cleaner// if it is inside oopicList<Type>, but do not want order n search// for element. void deleteCurrent() { if (currentPtr == NULL) return; // bail out if empty or at end // if at head of list, point head to next item if (currentPtr == theList->head) { theList->head = currentPtr->next; previousPtr = NULL; } else previousPtr->next = currentPtr->next; delete current(); // delete the data delete currentPtr; // delete the list item currentPtr = previousPtr; theList->nitems--; }};// __GNUC__ __BORLANDC__ _MSC_VER __KCC _CRAYT3E#endif// Some useful macros#define ApplyToList(function,theList,listType) { oopicListIter<listType> titer(theList); for(titer.restart();!titer.Done();titer++) titer.current()->function;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -