zoukankan      html  css  js  c++  java
  • C语言双链表遍历,插入,删除

    #include<stdio.h>
    #include<stdlib.h>
    #include <string.h>
    #define bzero(a, b)             memset(a, 0, b)//windows平台下无bzero函数。 增加宏拓展移植性
     struct node
     {
         int data;                //有效数据 
        struct node *pLast;//指向上一个节点的指针 
         struct node *pNext;//指向下一个节点的指针 
        
     };
      struct node * make_node(int data)
      {
          struct node *p=(struct node*)malloc(sizeof(struct node));
        if(NULL==p)
        {
            printf("malloc error
    ");
            return NULL;
        }
        //清理申请到的内存
        bzero(p,sizeof(struct node));
        //填充节点
         p->data=data;
         p->pLast=NULL;
         p->pNext=NULL;//将来要指向下一个节点的首地址 
                        //实际操作时将下一个节点的malloc 返回的指针给他。                    
        return p;
      }
      
      void ergodic(struct node *pH)//遍历
      {
          int cnt=0;
          struct node *p=pH;    
    /*     printf("------开始遍历------
    ");//这样包含头结点
         while(NULL!=p->pNext)
          {    
            printf("第%d节点数据为为%d
    ",cnt,p->data);    
            p=p->pNext;
            cnt++;    
          }
          printf("第%d节点数据为为%d
    ",cnt,p->data);    
        printf("------结束遍历------
    ");
        } */
        printf("------开始遍历------
    ");
         while(NULL!=p->pNext)
          {    
            cnt++;
            p=p->pNext;
            printf("第%d节点数据为为%d
    ",cnt,p->data);        
          }
        printf("------结束遍历------
    ");
      }
      
      void reverse_ergodic(struct node *pT)//反向遍历
      {
          int cnt=0;
          struct node *p=pT;    
        printf("------开始遍历------
    ");
         while(NULL!=p->pLast)
          {    
            cnt++;
            printf("第%d节点数据为为%d
    ",cnt,p->data);
            p=p->pLast;                
          }
        printf("------结束遍历------
    ");
      }
    void in_tail(struct node *pH,struct node *p_new)
    {    //先找到尾节点
        //插入
          int cnt=0;
          struct node *p=pH;
          while(NULL!=p->pNext)
          {
              p=p->pNext;
            cnt++;
          }
          p->pNext=p_new;   //插到之前最后的节点后面(后向指针)
          p_new->pLast=p;   //之前最后的节点后面防盗新节点的向前的指针(前向指针)
          pH->data=cnt+1;// 头节点数据代表链表个数
        //前指针的pLast与新指针的pNext无变动
    }
    void in_head(struct node *pH,struct node *p_new)
    {    //1。将原1好节点地址给新节点后向指针
        //2。将头指针指向新节点
        //3。原1号节点前向指针指向新节点
        //4。新节点前向指针指向头结点
          int cnt=0;
          struct node *p=pH;
          while(NULL!=p->pNext)
          {
              p=p->pNext;
            cnt++;
          }
          
         if(NULL==pH->pNext)
         {
             pH->pNext=p_new;
             p_new->pLast=pH;
             
         }else
         {
          p_new->pNext=pH->pNext;
          pH->pNext=p_new;
          p_new->pNext->pLast=p_new;        //不判断的话p_new->pNext->pLast会引发段错误
          p_new->pLast=pH;    
         }
          pH->data=cnt+1;// 头节点数据代表链表个数
        //前指针的pLast与新指针的pNext无变动
    }
    void del_1(struct node *pH,int num)//根据节点数删除 不能删除0(头节点)
      {
          
          //1找到
          //2删除
          //删除(释放内存。指向下一个)
          int cnt=0;
          struct node *p=pH;    
          struct node *p_sb;;//临时变量释放内存用
         while(NULL!=p->pNext)
          {        
            cnt++;
            if(num==cnt)
            {    
                p_sb=p->pNext;//p为预删除点的上一个节点
                p->pNext=p->pNext->pNext;//跳过欲删除节点指向下下个节点(删除正向节点)
                if(NULL==p->pNext)
                {
                    //说明P为现在最后一个节点
                }            
                else        
                {
                    p->pNext->pLast=p;//(删除反向节点)
                }                
                free(p_sb);//释放内存
                break;
            }
            p=p->pNext;//不满足上述条件时 寻找下一个节点
            
          }
      }
        void del_2(struct node *pH,int data)//删除指定数据
      {
          
          //1找到
          //2删除
          //删除(释放内存。指向下一个)
          struct node *p=pH;    
          struct node *p_sb;;//临时变量释放内存用
         while(NULL!=p->pNext)
          {        
            if(data==p->pNext->data)//p为预删除点的上一个节点
            {    p_sb=p->pNext;
                p->pNext=p->pNext->pNext;//跳过欲删除节点指向下下个节点(删除正向节点)
                
                if(NULL==p->pNext)
                {
                    //说明P为现在最后一个节点
                }            
                else        
                {
                    p->pNext->pLast=p;//(删除反向节点)
                }    
                free(p_sb);
                continue;
            }
            p=p->pNext;
            
          }
      }
    int main()
    {
        struct node *pHead=make_node(0);//初始化头节点;
        in_head(pHead,make_node(1));
        in_head(pHead,make_node(1));
        in_head(pHead,make_node(3));
        in_head(pHead,make_node(4));
    
        reverse_ergodic(pHead->pNext->pNext->pNext->pNext);
        ergodic(pHead); 
        
         ergodic(pHead);
        del_2(pHead,1);
        reverse_ergodic(pHead->pNext->pNext);
        ergodic(pHead);  
         return 0;
    } 
  • 相关阅读:
    查询程序,统计文件每个单词出现几次,对应的出现在哪一行
    适配器 STL
    非关联容器|hash|unordered_map/multimap,unordered_set/multiset
    函数对象
    ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)
    D. Connected Components Croc Champ 2013
    [Educational Codeforces Round 63 ] D. Beautiful Array (思维+DP)
    C. Vasily the Bear and Sequence Codeforces 336C(枚举,思维)
    Vasya and Beautiful Arrays CodeForces
    D. Happy Tree Party CodeForces 593D【树链剖分,树边权转点权】
  • 原文地址:https://www.cnblogs.com/PengfeiSong/p/6283185.html
Copyright © 2011-2022 走看看