从双链表操作继续分析代码质量

双向链表就是两个指针,一个指向前,另一个指向后。因此,我们可以从任何一个节点遍历。
在这里插入图片描述这次也是要实现一个有序双向链表。
思路:
我们把一个节点插入链表时候,有四种情况:
1、 新值可能插在链表中间
2、 新值可能插在链表结束位置
3、 新值可能插在链表开头
4、 新值插入的位置,既是开头就是结束位置。
算法也是比较简单:插入一个值,先拆链后上链。
下面就是代码展示。
//最开始写的代码

int LisrInsert3(struct node_t *psthead,struct node_t *pstnew)
{
     struct node_t *pos = NULL;

     if(NULL == psthead)
     {
          printf("psthead is null,please chech head\n");
          return -1;
     }
     if(NULL == pstnew)
     {
          printf("pstnew is null,please check pstnew\n");
     }
     
     for(pos = psthead->next; pos != psthead; pos = pos->next)
     {
          if(pstnew->data > pos->data)
               break;
     }
     //插入开始的位置
     if(pos->next == psthead)
     {
          pstnew->next = psthead->next;
          pstnew->prev = psthead;
          psthead->next->prev = pstnew;
          psthead->next = pstnew;
     }
     else
     {
          if(pos->next == psthead) //插入尾部
          {
               pos->next = pstnew;
               pstnew->prev = pos;
               pstnew->next = psthead;
               psthead->prev = pstnew;
          }
          else//不是尾部也不是开头
          {
               pos->next->prev = pstnew;
               pstnew->next = pos->next;
               pos->next = pstnew;
               pstnew->prev = pos;
          }
     }
     
}

第一次简化的代码:

int LisrInsert(struct node_t *psthead,struct node_t *pstnew)
{
     struct node_t *pos = NULL;

     if(NULL == psthead)
     {
          printf("psthead is null,please chech head\n");
          return -1;
     }
     if(NULL == pstnew)
     {
          printf("pstnew is null,please check pstnew\n");
     }
     
     for(pos = psthead; pos->next != psthead; pos = pos->next)
     {
          if(pstnew->data > pos->next->data)
               break;
     }
     //插入开始的位置
     if(pos == psthead)
     {
          pstnew->next = psthead->next;
          pstnew->prev = psthead;
          psthead->next->prev = pstnew;
          psthead->next = pstnew;
     }
     else
     {
          if(pos->next == psthead) //插入尾部
          {
               pos->next = pstnew;
               pstnew->prev = pos;
               pstnew->next = psthead;
               psthead->prev = pstnew;
          }
          else//不是尾部也不是开头
          {
               pos->next->prev = pstnew;
               pstnew->next = pos->next;
               pos->next = pstnew;
               pstnew->prev = pos;
          }
     }
     
}

第二次优化的代码:
//代码简化

int LisrInsert1(struct node_t *psthead,struct node_t *pstnew)
{
     struct node_t *pos = NULL;

     if(NULL == psthead)
     {
          printf("psthead is null,please chech head\n");
          return -1;
     }
     if(NULL == pstnew)
     {
          printf("pstnew is null,please check pstnew\n");
     }
     
     for(pos = psthead; pos->next != psthead; pos = pos->next)
     {
          if(pstnew->data > pos->next->data)
               break;
     }
     //插入开始的位置
     if(pos == psthead)
     {
          pstnew->next = psthead->next;
          pstnew->prev = psthead;
          psthead->next->prev = pstnew;
          psthead->next = pstnew;
     }
     else
     {
           pstnew->prev = pos;
           pstnew->next = pos->next;
          
           pos->next->prev = pstnew;
           pos->next = pstnew;
     }
     
}

最终版本的代码:
//代码简化2

int LisrInsert2(struct node_t *psthead,struct node_t *pstnew)
{
     struct node_t *pos = NULL;

     if(NULL == psthead)
     {
          printf("psthead is null,please chech head\n");
          return -1;
     }
     if(NULL == pstnew)
     {
          printf("pstnew is null,please check pstnew\n");
     }
     
     for(pos = psthead; pos->next != psthead; pos = pos->next)
     {
          if(pstnew->data > pos->next->data)
               break;
     }
      pstnew->prev = pos;
      pstnew->next = pos->next;
      pos->next->prev = pstnew;
      pos->next = pstnew;
     
     
}

其它代码:

//双链表插入的实现
int ListAddAfter(struct node_t *psthead,struct node_t *pstnew)
{
    

     if(NULL == psthead)
     {
          printf("psthead is null,please chech head\n");
          return -1;
     }
     if(NULL == pstnew)
     {
          printf("pstnew is null,please check pstnew\n");
     }
     
     psthead->prev->next = pstnew;
     pstnew->prev = psthead->prev;
     pstnew->next = psthead;
     psthead->prev = pstnew;
          
        
     
     
}
void display(struct node_t *psthead)
{
     struct node_t *pos = NULL;

     for(pos = psthead->next; pos != psthead; pos = pos->next)
     {
          printf("%d ",pos->data);
     }
     printf("\n");
}
void freeDoubleList(struct node_t *psthead)
{
      struct node_t *pos = NULL;

     if(NULL == psthead)
     {
          printf("psthead is null,please chech head\n");
          return;
     }
   
     for(pos =psthead->next;pos != psthead; pos = pos->next )
     {
          free(pos);
     }
     printf("free node finish\n");
}

主函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义一个双链表节点
struct node_t{
     int data;
     struct node_t *next;
     struct node_t *prev;
};
//定义一个头节点并初始化
struct node_t head = {0,&head,&head};

int ListAddAfter(struct node_t *psthead,struct node_t *pstnew);
void freeDoubleList(struct node_t *psthead);
void display(struct node_t *psthead);
int LisrInsert(struct node_t *psthead,struct node_t *pstnew);
int LisrInsert1(struct node_t *psthead,struct node_t *pstnew);
int LisrInsert2(struct node_t *psthead,struct node_t *pstnew);
int LisrInsert3(struct node_t *psthead,struct node_t *pstnew);
int main()
{
    
     struct node_t *node = NULL;
     int i = 0;
     int j;
     for(i = 0; i < 10; i++)
     {
          
           j = i*2;
           node = (struct node_t *)malloc(sizeof(struct node_t));
           node->data = j;
           //  ListAddAfter(&head,node);
           LisrInsert3(&head,node);
     }
#if 1
     //验证插入中间
      node = (struct node_t *)malloc(sizeof(struct node_t));
      node->data = 5;
      LisrInsert3(&head,node);
      //插入开头
       node = (struct node_t *)malloc(sizeof(struct node_t));
      node->data = 20;
       LisrInsert3(&head,node);
       //插入尾部
        node = (struct node_t *)malloc(sizeof(struct node_t));
      node->data = -1;
       LisrInsert3(&head,node);
#endif
     display(&head);
     freeDoubleList(&head);
    
     return 0;
}

总结:一开始,并不能写出体积最小的代码。因为对双链表的不同操作没有总结出共性,后来经过不断总结,发现了规律,才得出最终的版本。因此能写出体积小,效率更高的程序员,很佩服。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值