链表插入结点的两种思路

插入元素时,要先找到该元素的前一个元素。

a为当前结点;

b为要插入的结点;

c为a之后的结点;

相较删除结点两种思路,插入结点也有两种思路:

头插法:

1、保存c结点

b->next =c;

2、c结点重新赋值

c= b;

尾插法:

1、保存a的next(即c)

b ->next = a->next;

2、a->next重新赋值

a->next = b;

 

举例:无头结点的单链表为例,插入结点

方法一:理解为头插法,插在结点的前面

//在链表第i个位置插入元素
bool insertList(LinkList &slink,int i ,int e)
{
       /*
            找到第i个结点,在第i个结点的前面添加
            1、计数变量j
            2、变量指向当前变量,直至i
            3、循环条件,当前结点不为空且j<i
            
        */
        int j = 1;
        LinkList q = (LinkList)malloc(sizeof(Node));
        LinkList p = slink;
        p->data = 100;
        if(i<1) return false;
        if(i==1)
        {
            q->next = slink;
            slink = q;
            return true;
        }
        while(p&&j<i)//i>1且p不为空,未包含i=1和p为空的情况
        {            //发现p为空的情况和i=1的情况是可以合并的。
            p = p->next;
            j++;           
        }
        if(!p)
            return false;
        q->next = p;
        p = q;
        return true;
                              
}

 注意:如果始终在第一个位置上插入结点的话,以上代码可以简化如下:

//始终在链表第1个位置插入元素
slink =NULL;
bool insertList(LinkList &slink,int e)
{
        int j =0;
        LinkList q;
        while(j<100)
         {
             q= (LinkList)malloc(sizeof(Node));         
             p->data = e;
                
             q->next = slink;
             slink = q;
             j++;
        }  
        return true;                              
}

 以上的头插法对应的结点释放程序如下:(始终释放第一个结点)

//从头结点开始释放
slink =NULL;
bool dstroyList(LinkList &slink)
{
        
        LinkList q;
        while(slink!=NULL)
         {                           
             q = slink;
             slink = slink->next;
             free(q);           
        }  
        return true;                              
}

方法二:可以理解为尾插法,插在结点的后面 

//在链表第i个位置插入元素
bool insertList(LinkList &slink,int i ,int e)
{
       /*
            找到第i-1个结点,在第i-1个结点的后面添加
            1、计数变量j
            2、变量指向当前变量,直至第i-1
            3、循环条件,(一般情况,当前结点不为空,且j<i-1),特殊情况,当前结点为空的情况,
            j>i-1的情况.
            
            
            
        */
        int j =1;
        LinkList p = slink;
        LinkList temp = (LinkList)malloc(sizeof(Node));
        temp->data = 100;
        if(i<1) return false;
        if(i==1)//slink为空或者不为空,此条都适用
        {        //也就是说为空的时候,也可以当成不为空来理解。
            temp->next = slink;
            slink = temp;
        }
        while(p&&j<i-1)//i>2的情况;//少了i=1的情况。//从p=NULL看出少了链表为空的情况;
        {            //将链表为空和i=1的情况合并为上面的if语句。
            p = p->next;
            j++;
        }
        //if(!p||j>i-1)
        if(!p)    //此处不用j>i-1, 是因为前面已经排除了i<1的情况了
            return false;
        temp->next = p->next;
        p->next = temp;
        return true;          
}

 

总结:

1、写while循环的思路是先排除不满足循环条件的值;

while循环里是一般情况(大多数都满足的值)

跳出循环后,再排除一部分值;

检查没有进入到while循环的情况

最后,检查特殊情况能否合并。

2、头插法若始终在开头处插入数据的话,更简单

初始状态下(slink=NULL)的时候,插入第一个结点的思路,跟已经有1个结点,要插入第二个结点的思路是一致的。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值