算法之单向链表

算法之单向链表

算法之单向链表

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("\n");
      return ;
   }

   printf("%d\t",pLinkNode->data);
   printf("p2=%p\n",pLinkNode);
   print_node(pLinkNode->next);
}

4 插入链表



  /*4.链表插入数据*/
  /*
  插入位子从 0 开始
 */
  int _insert_node(link_node** pToNode,
                       link_node* pDataNode, int place)
  {
      if( NULL == *pToNode )
      {
          printf("超出链表长度,插入失败\n");
          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\n");
        return;
    }

    printf("1\n");
    pLinkNode = *pNode;
    *pNode=(*pNode)->next;
    free(pLinkNode);
    //printf("pdata=%d\tpnext=%p\n",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\tpdp=%p\t", pLinkNode,&(pLinkNode->data) );
        //printf("pdata=%d\tpnext=%p\n",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\n",pNode);
    printf("前:pnp=%p\tpdp=%p\t", pLinkNode,&(pLinkNode->data) );
    printf("pdata=%d\tpnext=%p\n",pLinkNode->data, pLinkNode->next);
    free(pNode);
    free(pLinkNode);
    printf("后:pnp=%p\tpdp=%p\t", pLinkNode,&(pLinkNode->data) );
    printf("pdata=%d\tpnext=%p\n",pLinkNode->data, pLinkNode->next);

    printf("ndata=%d\t",(pLinkNode->next)->data);
    printf("np=%p\n",(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("超出链表,删除失败\n");
        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 !\n");
        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)

posted on 2016-07-13 09:02  野书  阅读(229)  评论(0编辑  收藏  举报

导航