• 算法之单向链表


    算法之单向链表

    算法之单向链表

    1 链表结构体

    
    /*结构体*/
    typedef struct _link_node
    {
        struct _link_node* next;
        int data;
    }link_node;
    
    
    注意点
    定义结构体时,最好的顺序是由大到小的顺序定义结构体成员,如上,我先定义了
    一个指针类型,然后又定义了一个 int类型变量,它会占用16个字节,如果你顺序
    调过来,还是16个字节,但是它的效率会低很多,为什么会这样了?请看数据对齐相
    关内容; 《数据对齐详解》

    2 创建链表

    
    /*1.创建链表*/
    link_node* creat_node(int value)
    {
        link_node* pLinkNode;
        pLinkNode = (link_node*)malloc(sizeof(link_node));
        if(NULL ==pLinkNode)
           printf("Failt");
    
        pLinkNode->data = value;
        pLinkNode->next = NULL;
        return pLinkNode;
    }
    
    

    3 打印链表

    
    /*2.打印链表*/
    void print_node(link_node* pLinkNode)
    {
       if(NULL == pLinkNode)
       {
          printf("
    ");
          return ;
       }
    
       printf("%d	",pLinkNode->data);
       printf("p2=%p
    ",pLinkNode);
       print_node(pLinkNode->next);
    }
    
    

    4 插入链表

    
    
      /*4.链表插入数据*/
      /*
      插入位子从 0 开始
     */
      int _insert_node(link_node** pToNode,
                           link_node* pDataNode, int place)
      {
          if( NULL == *pToNode )
          {
              printf("超出链表长度,插入失败
    ");
              return -1;
          }
          if(1==place )
          {
              pDataNode->next = (*pToNode)->next;
              (*pToNode)->next=pDataNode;
              return 0;
          }
          _insert_node(&(*pToNode)->next, pDataNode, place-1);
      }
    
    
      void insert_node(link_node** pToNode, int place, int value)
      {
          link_node* pDataNode;
          pDataNode = creat_node(value);
          if(0 == place)
          {
              pDataNode->next = *pToNode;
              *pToNode = pDataNode;
              return;
          }
          if(place<0 )    /*和法性有问题,插入位子容易过大*/
          {
              printf("插入位子错误");
              return;
          }
    
          _insert_node(pToNode, pDataNode, place);
    }
    
    
      

    5 删除链表

    
    /*5.删除链表*/
    #if 1
    /* 递归方法 */
    void delete_node(link_node** pNode)
    {
        link_node* pLinkNode;
        if(NULL==pNode || NULL==*pNode)
        {
            printf("afa
    ");
            return;
        }
    
        printf("1
    ");
        pLinkNode = *pNode;
        *pNode=(*pNode)->next;
        free(pLinkNode);
        //printf("pdata=%d	pnext=%p
    ",pLinkNode->data, pLinkNode->next); //测试
        delete_node(pNode);
    }
    
    #else
    /*普通方法*/
    void delete_node(link_node** pNode)
    {
        link_node *pLinkNode;
        while(NULL != *pNode)
        {
            pLinkNode=*pNode;
            *pNode=(*pNode)->next;
            free(pLinkNode);
    
            /*调试信息*/
            //printf("pnp=%p	pdp=%p	", pLinkNode,&(pLinkNode->data) );
            //printf("pdata=%d	pnext=%p
    ",pLinkNode->data, pLinkNode->next);
        }
    }
    #endif
    
    注意事项
    在我调试删除链表时发现一个奇怪现象 本奇葩现象在单向链表中发现

    1.在带有指针域和数据域结构体中,用malloc()函数分配空间,再用free()函数
    释放空间,在释放空间过程中,被释放空间的指针域会产生一个随机数,而数据域的
    值不会发生任何改变,如果你通过被释放空间的指针域访问下一个地址,你可以在
    数据域中看到一个随机的数据,但指针域所指的地址为NULL。

    测试代码
    
    
    #include
    #include
    typedef struct _link_node
    {
        struct _link_node* next;
        int data;
    }link_node;
    
    int main()
    {
        link_node* pLinkNode;
        link_node* pNode;
    
        pLinkNode = (link_node*)malloc(sizeof(struct _link_node));
        pNode = (link_node*)malloc(sizeof(struct _link_node));
        pLinkNode->data = 16;
        pNode->data = 6;
        pLinkNode->next = pNode;
    
        printf("%p
    ",pNode);
        printf("前:pnp=%p	pdp=%p	", pLinkNode,&(pLinkNode->data) );
        printf("pdata=%d	pnext=%p
    ",pLinkNode->data, pLinkNode->next);
        free(pNode);
        free(pLinkNode);
        printf("后:pnp=%p	pdp=%p	", pLinkNode,&(pLinkNode->data) );
        printf("pdata=%d	pnext=%p
    ",pLinkNode->data, pLinkNode->next);
    
        printf("ndata=%d	",(pLinkNode->next)->data);
        printf("np=%p
    ",(pLinkNode->next)->next);
        return 0;
    }
    
    
    

    6 删除结点

    
    
    /*6.删除结点*/
    void delete_one_node(link_node** pNode, int place)
    {
        link_node* pNext;
        if(NULL==*pNode || NULL==pNode)
        {
            printf("超出链表,删除失败
    ");
            return;
        }
        if(1== place)
        {
            *pNode=(*pNode)->next;
            return;
        }
        if(2 == place)
        {
            pNext=(*pNode)->next;
            (*pNode)->next = pNext->next;
            free(pNext);
            return;
       }
       delete_one_node(&(*pNode)->next,place-1);
    }
    
    
    

    7 查找数据

    
    /*7. 查找数据*/
    link_node* find_data(link_node** pNode, int value)
    {
        if(NULL==(*pNode))
        {
            printf("not found !
    ");
            return NULL;
        }
        if(value == ((*pNode)->data))
        {
            return *pNode;
        }
        find_data(&(*pNode)->next, value);
    
    }
    
    

    8 统计数据

    
    
    /*8.统计数据*/
    int count_node(link_node* pLinkNode)
    {
        if(NULL==pLinkNode)
           return 0;
        return 1+count_node(pLinkNode->next);
    }
    

    9 测试代码

    
    
    void main()
    {
        link_node* pLinkNode;
        link_node* pNode;
        int n;
        pLinkNode = creat_node(5);
        add_data(&pLinkNode, 7);
        add_data(&pLinkNode, 8);
        add_data(&pLinkNode, 9);
        print_node(pLinkNode);
    
        delete_node(&pLinkNode);
    
        print_node(pLinkNode);
    }
    
    

    Date: a date, fixed, of a format string for format-time-string

    Author: 野书

    Created: 2016-07-14 四 20:44

    Emacs 24.5.1 (Org mode 8.2.10)

  • 相关阅读:
    JS控制台打印星星,总有你要的那一款~
    css居中方法
    line-height
    position定位
    IE盒子模型
    CSS中的盒模型
    CSS中的BEM命名
    循环语句总结(代码以C#为例)
    程序设计中的数学思维函数总结(代码以C#为例)
    转:SpringBoot 自定义异常@ContollerAdvice ExceptionHandler不起作用
  • 原文地址:https://www.cnblogs.com/wild-book/p/5665658.html
Copyright © 2020-2023  润新知