300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > c语言双向链表实现航班系统 双向链表C语言实现

c语言双向链表实现航班系统 双向链表C语言实现

时间:2019-08-01 18:42:19

相关推荐

c语言双向链表实现航班系统 双向链表C语言实现

#ifndef __STDLIST_H__

#define __STDLIST_H__

typedef struct tagSTDNODE STDNODE, *LPSTDNODE;

typedef struct tagSTDLIST STDLIST, *LPSTDLIST;

// 链表数据结构

struct tagSTDNODE {

LPSTDNODE lpPrev;

LPSTDNODE lpNext;

};

// 链表节点结构

struct tagSTDLIST {

LPSTDNODE lpHead;

LPSTDNODE lpTail;

};

// 用于链表扩展的宏

#define NODE_INITIALIZER ((STDNODE){ .lpPrev = NULL, .lpNext = NULL, })

#define LIST_INITIALIZER ((STDLIST){ .lpHead = NULL, .lpTail = NULL, })

#define DECLARELISTNODE()STDNODE __snStdNode

#define INIT_LISTNODE() __snStdNode = NODE_INITIALIZER

// 初始化链表

STATIC INLINE

LPSTDLIST TWINAPI StdListInit(

LPSTDLIST lpList

) {

lpList->lpHead = NULL;

lpList->lpTail = NULL;

return lpList;

}

// 获取链表头部节点

STATIC INLINE

LPSTDNODE TWINAPI StdListGetHeadNode(

LPSTDLIST lpList

) {

return lpList->lpHead;

}

// 获取链表尾部节点

STATIC INLINE

LPSTDNODE TWINAPI StdListGetTailNode(

LPSTDLIST lpList

) {

return lpList->lpTail;

}

// 获取给定节点的下一个节点

STATIC INLINE

LPSTDNODE TWINAPI StdListGetNextNode(

LPSTDNODE lpNode

) {

return lpNode->lpNext;

}

// 获取给定节点的上一个节点

STATIC INLINE

LPSTDNODE TWINAPI StdListGetPrevNode(

LPSTDNODE lpNode

) {

return lpNode->lpPrev;

}

// 在链表头部插入一个节点

STATIC INLINE

VOID TWINAPI StdListPushFront(

LPSTDLIST lpList,

LPSTDNODE lpNode

) {

lpNode->lpPrev = NULL;

lpNode->lpNext = lpList->lpHead;

if(lpList->lpHead)

lpList->lpHead->lpPrev = lpNode;

else

lpList->lpTail = lpNode;

lpList->lpHead = lpNode;

}

// 在链表尾部插入一个节点

STATIC INLINE

VOID TWINAPI StdListPushBack(

LPSTDLIST lpList,

LPSTDNODE lpNode

) {

lpNode->lpNext = NULL;

lpNode->lpPrev = lpList->lpTail;

if(lpList->lpTail)

lpList->lpTail->lpNext = lpNode;

else

lpList->lpHead = lpNode;

lpList->lpTail = lpNode;

}

// 在指定节点后插入一个节点

STATIC INLINE

VOID TWINAPI StdListInsert(

LPSTDLIST lpList,

LPSTDNODE lpAfter,

LPSTDNODE lpNode

) {

if(lpAfter) {

if(lpAfter->lpNext)

lpAfter->lpNext->lpPrev = lpNode;

else

lpList->lpTail = lpNode;

lpNode->lpPrev = lpAfter;

lpNode->lpNext = lpAfter->lpNext;

lpAfter->lpNext = lpNode;

} else {

StdListPushFront(lpList, lpNode);

}

}

// 从链表头部弹出一个节点

STATIC INLINE

LPSTDNODE TWINAPI StdListPopFront(

LPSTDLIST lpList

) {

if(lpList->lpHead) {

LPSTDNODE lpNode = lpList->lpHead;

if(lpList->lpHead->lpNext)

lpList->lpHead->lpNext->lpPrev = NULL;

else

lpList->lpTail = NULL;

lpList->lpHead = lpList->lpHead->lpNext;

lpNode->lpPrev = lpNode->lpNext = NULL;

return lpNode;

} else {

return NULL;

}

}

// 从链表尾部弹出一个节点

STATIC INLINE

LPSTDNODE TWINAPI StdListPopBack(

LPSTDLIST lpList

) {

if(lpList->lpTail) {

LPSTDNODE lpNode = lpList->lpTail;

if(lpList->lpTail->lpPrev)

lpList->lpTail->lpPrev->lpNext = NULL;

else

lpList->lpHead = NULL;

lpList->lpTail = lpList->lpTail->lpPrev;

lpNode->lpPrev = lpNode->lpNext = NULL;

return lpNode;

} else {

return NULL;

}

}

// 从链表中删除给定节点

STATIC INLINE

LPSTDNODE TWINAPI StdListRemove(

LPSTDLIST lpList,

LPSTDNODE lpNode

) {

if(lpNode->lpPrev)

lpNode->lpPrev->lpNext = lpNode->lpNext;

else

lpList->lpHead = lpNode->lpNext;

if(lpNode->lpNext)

lpNode->lpNext->lpPrev = lpNode->lpPrev;

else

lpList->lpTail = lpNode->lpPrev;

return lpNode;

}

// 检查链表是否为空

STATIC INLINE

BOOL TWINAPI StdListIsEmpty(

LPSTDLIST lpList

) {

if(lpList->lpHead || lpList->lpTail)

return FALSE;

else

return TRUE;

}

// 获取链表中的节点数

STATIC INLINE

LONG TWINAPI StdListGetSize(

LPSTDLIST lpList

) {

LONG lnSize = 0;

LPSTDNODE lpNode = StdListGetHeadNode(lpList);

while(lpNode) {

++ lnSize;

lpNode = StdListGetNextNode(lpNode);

}

return lnSize;

}

// 合并两个链表

STATIC INLINE

LPSTDLIST TWINAPI StdListCombine(

LPSTDLIST lpList1,

LPSTDLIST lpList2

) {

if(!StdListIsEmpty(lpList2)) {

if(!StdListIsEmpty(lpList1)) {

lpList1->lpTail->lpNext = lpList2->lpHead;

lpList2->lpHead->lpPrev = lpList1->lpTail;

lpList1->lpTail = lpList2->lpTail;

} else {

lpList1->lpHead = lpList2->lpHead;

lpList1->lpTail = lpList2->lpTail;

}

lpList2->lpHead = lpList2->lpTail = NULL;

}

return lpList1;

}

#endif//__STDLIST_H__

算法本身没有什么特别的地方,为什么说这是一个通用双向链表呢?奥妙就在那四个用于扩展的宏。利用这几个宏你可以将这个双向链表扩展到任意结构。

例如,我们要实现一个消息队列,那么我们可以这样定义消息节点:

typedef struct tagMSGNODE {

DECLARELISTNODE();

HWND hWnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

} MSGNODE, *LPMSGNODE;

而消息队列则可以直接用LISTNODE结构来表示:

STDLIST lstMsgQueue;

这样我们就可以用刚刚定义的函数来对这个消息队列进行操作了:

// 向消息队列插入一个消息

LPMSGNODE lpMsgNode = MemAlloc(SIZEOF(MSGNODE));

lpMsgNode->INIT_LISTNODE();

lpMsgNode->hWnd = hWnd;

lpMsgNode->uMsg = WM_PAINT;

lpMsgNode->wParam = NULL;

lpMsgNode->lParam = NULL;

StdListPushBack(&lstMsgQueue, (LPSTDNODE)lpMsgNode);

// 从消息队列取出一个消息

LPMSGNODE lpMsgNode = (LPMSGNODE)StdListPopFront(&lstMsgQueue);

// 删除所有属于hWnd的消息

LPMSGNODE lpTemp = (LPMSGNODE)StdListGetHeadNode(&lstMsgQueue);

while(lpTemp) {

LPMSGNODE lpNext = (LPMSGNODE)StdListGetNextNode(&lstMsgQueue, (LPSTDNODE)lpTemp);

if(lpTemp->hWnd == hWnd) {

StdListRemove(&lstMsgQueue, (LPSTDNODE)lpTemp);

MemFree(lpTemp);

}

lpTemp = lpNext;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。