zoukankan      html  css  js  c++  java
  • 【链表】链表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;
        }
    }
  • 相关阅读:
    SSLZYC NOIP
    SSLZYC 懒惰的奶牛①
    SSLZYC 小麦高度
    Pythonlog() 函数
    详细解读Python中的__init__()方法
    详细解读Python中的__init__()方法
    Linux软件安装中RPM与YUM 区别和联系
    Linux软件安装中RPM与YUM 区别和联系
    【我的物联网成长记】设备如何进行选型?
    【我的物联网成长记】设备如何进行选型?
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3404142.html
Copyright © 2011-2022 走看看