【链表】链表OFFSET偏移头插法
//链表的头插法 /***************************************/ //运用了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; } }