zoukankan      html  css  js  c++  java
  • C语言动态链表数据结构

    链表的操作增删改查

    typedef int DATA;
    
    struct SNode
    {
        DATA data;
        SNode* pNext;
    };
    
    SNode* g_head=NULL;//全局变量
    
    //从头部添加
    void AddHead(DATA nNum)
    {
        SNode* p = (SNode*)malloc(sizeof(SNode));//C语言的方式
        //SNode* p = new SNode;//C++ 方式
        p->data = nNum;
        p->pNext = g_pHead;
    
        g_pHead = p;
    }
    
    
    //从尾部添加
    void AddTail(DATA nNum)
    {
        SNode* p = (SNode*)malloc(sizeof(SNode));//C语言的方式
        pNew->data = nNum;
        pNew->pNext = NULL;
    
        if (!g_pHead)
        {
            g_pHead = pNew;
            return;
        }
    
        SNode* p = g_pHead;
        SNode* p1 = NULL;
        while (p)
        {
            p1 = p;
            p= p->pNext;
        }
    
        //跳出循环时,p1记录的时最后一个节点,让最后一个节点的pNext指向新创建的节点
        p = p1;
        p->pNext = pNew;
    
    
        //另一种写法
        //while(p->pNext != NULL)//循环遍历,当下一个节点为空说明到尾部了
        //    p=p->pNext;
            //p->pNext = pNew;
    }
    
    //找到,返回找节点位置;失败返回-1
    int FindNodeIndex(DATA nNum)
    {
        SNode* p = g_pHead;
        int i =0;
        while(p)
        {
            if (p->data == nNum)
            {
                return i;
            }
                
            p = p->pNext;
            ++i;
        }
    
        return -1;
    }
    
    //删除成功返回-1;失败返回0
    int DeleteNode(DATA nNum)
    {
        SNode* p = g_pHead;
        SNode* p1 = NULL;//记录前一个节点
    
        if (p == NULL)//当前链表为空
        {
            return -1;
        }
    
        //头节点没有前一个节点,要特殊处理
        if (p->data == nNum)
        {
            g_pHead = p->pNext;
            delete p;
            return 0;
        }
        while(p)
        {
            if (p->data == nNum)
            {
                //删除当前节点时,让当前节点的前一个节点的pNext指向当前节点的后一个节点
                p1->pNext = p->pNext;
                delete p;
                return 0;
            }
            p1= p;//记录前节点
            p = p->pNext;
        }
    
        return -1;
    }
    
    //修改指定节点的值
    void ModifyNode(DATA oldNum,DATA newNum)
    {
        SNode* p = g_pHead;
        while(p)//
        {
            if (p->data == oldNum)
            {
                p->data = newNum;
            }
                p = p->pNext;
        }
    }
    
    //打印所有节点
    void PrintALL()
    {
        SNode* p = g_pHead;
        if (p == NULL)
        {
            printf("当前链表为空
    ");
            return;
        }
        while(p)//
        {
            printf("%d
    ",p->data);
            p = p->pNext;
        }
    }
    
    //成功返回0;失败返回-1
    int FindNode(DATA nNum)
    {
        SNode* p = g_pHead;
        while (p)
        {
            if (p->data == nNum)
            {
                return 0;
            }
    
            p=p->pNext;
        }
        return -1;
    }
    
    //在某个节点之后插入新节点;成功返回0;失败返回-1
    int InsertNode(DATA npos,DATA nNum)
    {
        SNode* pNew = new SNode;//C++ 方式
        pNew->data = nNum;
        pNew->pNext = NULL;
        
       SNode* p = g_pHead;
    
        //if (p->data == npos)//头结点
        //{
        //    pNew->pNext=p->pNext;//头节点指向的下一个节点指针放到新节点的pNext
        //    p->pNext=pNew;//头节点pNext指向新节点
    
        //    return 0;
        //}
    
        while(p)
        {
            if (p->data == npos)
            {
                pNew->pNext = p->pNext;
                p->pNext=pNew;
    
                return 0;
            }
                p = p->pNext;
        }
    
        return -1;
    }
    
    void DeleteAll()
    {
        SNode* p = g_pHead;
        SNode* p1 = NULL;
        while(p)
        {
            p1=p;
            p= p->pNext;
    
            delete p1;
        }
    
        g_pHead = NULL;
    }
    
    int main()
    {
        DeleteNode(999);//链表为空的时候,删除要加判断
    
        lAddHead(1);
        lAddHead(2);
        AddHead(3);
        puts("修改前");
        PrintALL();
        ModifyNode(2,-88);
        puts("修改后");
        lPrintALL();
    
        int i = FindNodeIndex(-88);
        if (i >= 0)
        {
            cout << "" << i+1 << "个节点找到" <<endl;
        }
    
        //删除节点
        i = DeleteNode(3);//头部删除要特殊处理
        if (i == 1)
        {
            cout << "删除节点成功!" << endl;
        }
        else
        {
            cout << "删除节点失败!" << endl;
        }
        PrintALL();
    
        puts("尾部添加");
        AddTail(4);
        PrintALL();
    
        //修改节点
        ModifyNode(-88,0);
        puts("插入节点3");
        //插入节点
        i = list.InsertNode(4,3);
    
        list.PrintALL();
    
        puts("清空链表");
        DeleteAll();
        PrintALL();
      return 0;
    }

    1.头部插入

    2.尾部插入

    3.在指定节点位置后面插入新节点

      例如:在节点2后面插入新节点4

     

    中间插入新节点4,让节点2的pNext赋值给新节点4的pNext,然后让新节点4的地址赋值给节点2的pNext

    4.删除节点

      

    注意:如果删除的是头节点,要特殊处理,因为头节点没有前面的节点,所以头节点的pNext赋值给g_head;

  • 相关阅读:
    vtk体绘制时采样的起点使用噪声纹理来进行扰动
    转:轻松搞死VS
    虚拟华师(UDK)
    虚拟手术中的血流模拟(Physx+OpenGL)
    要找工作了,研究工作得暂停了
    MC+多个emitter成功把撕裂场景基本解决了
    鸭梨很大
    这世界好人多啊
    JS代码的格式化和压缩
    FusionCharts使用实例
  • 原文地址:https://www.cnblogs.com/chechen/p/9425524.html
Copyright © 2011-2022 走看看