//鏈表的頭插法 /***************************************/ //運用了OFFSET的宏定義 //經過GetNextPtr來實現OFFSET偏移 //最終實現鏈表結點的頭插法。 //麻省算法導論 /***************************************/ #include<iostream> #include<windows.h> using namespace std; #define OFFSET(x,m) (unsigned long)(&((x*)0)->m) /****************結點*****************/ typedef struct _NODE_ { int a; int b; _NODE_* pNext; }Node,*pNode; /*************************************/ /***************函數聲明*************/ void InitNode(pNode* ppNodeTemp); pNode* GerNextPtr(pNode pNodeTemp); void LinkNode(pNode pNodeNew); void FreeList(); pNode g_pHead = NULL; unsigned long g_Offset = 0; /************************************/ //主函數用於測試輸入建立一個有三個結點的鏈表 int main() { pNode pNodeTemp = NULL; for(int i =0;i<3;i++) { InitNode(&pNodeTemp); //建立 if(pNodeTemp!=NULL) { LinkNode(pNodeTemp); //鏈接 } } pNode pTravel = g_pHead; while(pTravel != NULL) { cout<<pTravel->a<<endl; pTravel = pTravel->pNext; } //程序結束時,釋放內存 FreeList(); return 0; } //這裏傳參是傳一個二維指針ppNode,而後解*後恰好是指針自己 //再進行動態內存申請。 //並賦值 void InitNode(pNode* ppNodeTemp) { *ppNodeTemp = new Node; if(*ppNodeTemp != NULL) { (*ppNodeTemp)->a = 10; (*ppNodeTemp)->b = 20; (*ppNodeTemp)->pNext = NULL; } else { *ppNodeTemp = NULL; } } //和OFFSET一塊兒實現指針的後移, //這裏由於有a,b兩個int型變量在Node結構體中, //因此下移的字節數應該是8個 pNode* GetNextPtr(pNode pNodeTemp) { char* p =(char*)pNodeTemp; return (pNode*)(p+OFFSET(Node,pNext)); } //鏈接結點 void LinkNode(pNode pNodeNew) { //二維指針解*恰好是一維指針 //將其賦值爲g_pHead至關於 pNodeNew->pNext = g_pHead //由於經過GerNextPtr 下移了8個字節 *GetNextPtr(pNodeNew) = g_pHead; //而後將頭賦爲pNodeNew //實現了頭部插入 g_pHead = pNodeNew; } //簡單釋放內存 void FreeList() { pNode pNodeDel = g_pHead; while(pNodeDel != NULL) { g_pHead = g_pHead->pNext; delete pNodeDel; pNodeDel = g_pHead; } }