【例子】求凸包算法(扫描法)

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef char V_INT8; // 8 bit signed typedef unsigned char V_UINT8; // 8 bit unsigned typedef short V_INT16; // 16 bit signed typedef unsigned short V_UINT16; // 16 bit unsigned typedef int V_INT32; // 32 bit signed typedef unsigned int V_UINT32; // 32 bit unsigned template <class T> inline void VSwap( T &left , T &right ) { T tmp = left; left = right; right = tmp; } #define TRUE 1 #define FALSE 0 #define listHeadInit(name) { &(name), &(name) } #define OFFSETOF( TYPE, MEMBER ) ( (V_UINT32)( &( (TYPE*)NULL )->MEMBER ) ) //从成员指针得到所在对象指针 #define GetEntryFromMember(ptr, type, member) / ( (type *)( (char *)(ptr) - OFFSETOF(type, member) ) ) #define GetGListItPtr(ptr) GetEntryFromMember( (ptr), VGListIterator, _node ) //双向链表移除节点方便 struct VListHead { friend class VListIterator; friend class VStack; public: VListHead() { initListHead(); } void initListHead() { next = this; prev = this; } void addListNext( VListHead *head ) { addToList( head, head->next ); } void addListPrev( VListHead *head ) { addToList( head->prev, head ); } //将当前节点从链表中删除 void delList() { removeFromList( prev, next); next = NULL; prev = NULL; } void delListInit() { removeFromList( prev, next ); initListHead(); } bool isEmpty() const { return next == this; } /////////////////////////////// bool hasOnlyItem() const { return next && ( next == prev ); } bool isNodeOffList() const //脱离链表 { return ( next == this ) || ( next == NULL ) || ( prev == NULL ); } void moveListNext( VListHead *head ) { removeFromList( prev, next ); addListNext( head ); } void moveListPrev( VListHead *head ) { removeFromList( prev, next ); addListPrev( head ); } private: VListHead *next; VListHead *prev; void addToList( VListHead *prv, VListHead *nxt ) { nxt->prev = this; this->next = nxt; this->prev = prv; prv->next = this; } //移除prv和nxt之间的节点 static void removeFromList( VListHead *prv, VListHead *nxt ) { nxt->prev = prv; prv->next = nxt; } }; struct VListIterator { public: VListIterator( VListHead *h ):_list( h ), _curItem(h->next), _nxtItem( NULL ) { } VListHead * operator++() { _curItem = _curItem->next; return _curItem; } VListHead * operator--() { _curItem = _curItem->prev; return _curItem; } VListHead * start() { _curItem = _list->next; return _curItem; } //逆序开始 VListHead * revStart() { _curItem = _list->prev; return _curItem; } bool isEnd() const { return _list == _curItem; } bool isEmpty() const { return _list->isEmpty(); } VListHead *curItem() const { return _curItem; } //判断_nxtItem是否有效,同时清空 VListHead *nextItem() { VListHead *pRet = _nxtItem; _nxtItem = NULL; return pRet; } int updateCurItem() { VListHead *newItem = nextItem(); if ( newItem ) { _curItem = newItem; return TRUE; } return FALSE; } protected: VListHead *const _list; //表头节点 VListHead *_curItem; VListHead *_nxtItem; }; #define VRepeatForNTimes(N) for ( int i = (N); i > 0; --i ) #define VListForEach(it) for ( it.start(); !it.isEnd(); ++it ) #define VListForEachRev(it) for ( it.revStart(); !it.isEnd(); --it ) struct VStack { public: VStack() { } VListHead * topItem( int ord = 0 ) { VListIterator it( &_head ); VListForEach( it ) { if ( --ord < 0 ) { return it.curItem(); } } return NULL; } void push( VListHead *node ) { node->addListNext( &_head ); } VListHead * pop() { VListHead *ret = topItem(); delTop(); return ret; } private: int delTop() { _head.next->delListInit(); return TRUE; } VListHead _head; }; struct VPoint { int x; int y; }; struct VItem { VItem( const VPoint&pt ):_pot( pt ) { } VListHead _node; VListHead _stackNode; VPoint _pot; }; #define GetItemList(ptr) GetEntryFromMember( (ptr), VItem, _node ) #define GetItemStack(ptr) GetEntryFromMember( (ptr), VItem, _stackNode ) int CalVectPrdct( int x1, int y1, int x2, int y2 ) { return (x1*y2 - x2*y1); } int CalVectPrdct( const VPoint&p0, const VPoint&p1, const VPoint&p2 ) { return CalVectPrdct( p0.x - p1.x, p0.y - p1.y, p2.x - p1.x, p2.y - p1.y ); } int CalDistnc2( const VPoint&p0, const VPoint&p1 ) { return (p0.x - p1.x)*(p0.x - p1.x) + (p0.y - p1.y)*(p0.y - p1.y); } VListHead *InitPots( VPoint pots[], int n ) { int yMin = 999999; int xVal = 999999; int idx = -1; for( int i = 0; i < n; ++i ) { if ( pots[i].y < yMin || (pots[i].y == yMin && pots[i].x < xVal) ) { yMin = pots[i].y; xVal = pots[i].x; idx = i; } } VSwap( pots[0], pots[idx] ); VListHead *head = new VListHead; for( int k = 0; k < n; ++k ) { VListIterator it( head ); it.start(); ++it; for ( ; !it.isEnd(); ++it ) { VItem *cur = GetItemList( it.curItem() ); int prdctVal = CalVectPrdct( pots[k], pots[0], cur->_pot ); if ( prdctVal > 0 ) { VItem *item = new VItem( pots[k] ); item->_node.addListPrev( it.curItem() ); break; } else if ( prdctVal == 0 ) { if ( CalDistnc2( pots[k], pots[0] ) > CalDistnc2( pots[0], cur->_pot ) ) { cur->_pot = pots[k]; } break; } } if ( it.isEnd() ) { VItem *item = new VItem( pots[k] ); item->_node.addListPrev( head ); } } return head; } VListHead *CalStkPots( VListHead *head ) { VStack stack; VListIterator it( head ); VListForEach( it ) { VItem *cur = GetItemList( it.curItem() ); VListHead *top = NULL; VListHead *top2 = NULL; while ( (top = stack.topItem()) && (top2=stack.topItem(1)) ) { VItem *itemTop = GetItemStack( top ); VItem *itemTop2 = GetItemStack( top2 ); int vectPrdct = CalVectPrdct( itemTop2->_pot, itemTop->_pot, cur->_pot ); if ( vectPrdct < 0 ) { break; } else { stack.pop(); } } stack.push( &cur->_stackNode ); } VListHead *out = new VListHead; VListHead *top = NULL; while (top = stack.pop()) { top->addListNext( out ); } return out; } int main(int argc, char* argv[]) { int n; printf( "nums:" ); scanf( "%d", &n ); VPoint *pots = new VPoint[n]; for( int i = 0; i < n; ++i ) { printf( "pots[%d].x:", i ); scanf( "%d", &pots[i].x ); printf( "pots[%d].y:", i ); scanf( "%d", &pots[i].y ); } VListHead *head = InitPots( pots, n ); VListHead *out = CalStkPots( head ); printf( "out pots:/n" ); VListIterator it( out ); VListForEach( it ) { VItem *item = GetItemStack( it.curItem() ); printf( "x:%d,y:%d/n", item->_pot.x, item->_pot.y ); } VListIterator it2( head ); for ( it2.start(); !it2.isEnd(); ) { VItem *item = GetItemList( it2.curItem() ); ++it2; item->_node.delListInit(); delete item; } delete out; delete head; delete []pots; return 0; }

你可能感兴趣的:(算法,struct,list,null,delete,Class)