#ifndef __stdlist_h__
#define __stdlist_h__
typedef struct tagstdnode stdnode, *lpstdnode;
typedef struct tagstdlist stdlist, *lpstdlist;
// 鍊錶資料結構
struct tagstdnode ;
// 鍊錶節點結構
struct tagstdlist ;
// 用於鍊錶擴充套件的巨集
#define node_initializer ((stdnode))
#define list_initializer ((stdlist))
#define declarelistnode() stdnode __snstdnode
#define init_listnode() __snstdnode = node_initializer
// 初始化鍊錶
static inline
lpstdlist twinapi stdlistinit(
lpstdlist lplist
) // 獲取鍊錶頭部節點
static inline
lpstdnode twinapi stdlistgetheadnode(
lpstdlist lplist
) // 獲取鍊錶尾部節點
static inline
lpstdnode twinapi stdlistgettailnode(
lpstdlist lplist
) // 獲取給定節點的下乙個節點
static inline
lpstdnode twinapi stdlistgetnextnode(
lpstdnode lpnode
) // 獲取給定節點的上乙個節點
static inline
lpstdnode twinapi stdlistgetprevnode(
lpstdnode lpnode
) // 在鍊錶頭部插入乙個節點
static inline
void twinapi stdlistpushfront(
lpstdlist lplist,
lpstdnode lpnode
) // 在鍊錶尾部插入乙個節點
static inline
void twinapi stdlistpushback(
lpstdlist lplist,
lpstdnode lpnode
) // 在指定節點後插入乙個節點
static inline
void twinapi stdlistinsert(
lpstdlist lplist,
lpstdnode lpafter,
lpstdnode lpnode
) else
} // 從鍊錶頭部彈出乙個節點
static inline
lpstdnode twinapi stdlistpopfront(
lpstdlist lplist
) else
} // 從鍊錶尾部彈出乙個節點
static inline
lpstdnode twinapi stdlistpopback(
lpstdlist lplist
) else
} // 從鍊錶中刪除給定節點
static inline
lpstdnode twinapi stdlistremove(
lpstdlist lplist,
lpstdnode lpnode
) // 檢查鍊錶是否為空
static inline
bool twinapi stdlistisempty(
lpstdlist lplist
) // 獲取鍊錶中的節點數
static inline
long twinapi stdlistgetsize(
lpstdlist lplist
) return lnsize;
} // 合併兩個鍊錶
static inline
lpstdlist twinapi stdlistcombine(
lpstdlist lplist1,
lpstdlist lplist2
) else
lplist2->lphead = lplist2->lptail = null;
} return lplist1;
} #endif//__stdlist_h__
演算法本身沒有什麼特別的地方,為什麼說這是乙個通用雙向鍊錶呢?奧妙就在那四個用於擴充套件的巨集。利用這幾個巨集你可以將這個雙向鍊錶擴充套件到任意結構。
例如,我們要實現乙個訊息佇列,那麼我們可以這樣定義訊息節點:
typedef struct tagmsgnode 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)
lptemp = lpnext;
}
c語言實現雙向鍊錶
單向鍊錶有一定的缺陷,其中乙個就是只能一條路走到黑,只能前進不能後退,但雙向鍊錶就解決了這一問題 include include typedef struct node node,linklist void create list tail linklist l 頭插法建立 void create ...
C語言實現雙向鍊錶
1.定義兩個結構體,乙個表示鍊錶的乙個單元,另乙個表示鍊錶的頭結點 2.鍊錶的初始化 必須讓頭結點的next和prev指向自己 清除 不刪除頭結點 銷毀 刪除頭結點 3.增操作 每次增加需要開闢乙個單元,所以直接建立乙個函式用來建立單元 頭插 尾插 pos結點之前插 4.刪操作 分為三種 刪除pos...
C語言實現雙向鍊錶
linklist.h ifndef linklist h define linklist h 節點 包含前置指標和後置指標 struct listnode struct list define listnextnode x x x next null define listhead x x x he...