2.16√ 无头结点单链表插入元素

因为是无头结点单链表L,L指向第一个结点,所以在插入元素时要考虑插入位置是否在表头,如果是,则要将新结点的next指针指向第一个结点,同时将L重新指向新结点。

重点在于❗❗【指针作为参数时,如何改变它所指向的值】❗❗

在C语言中, 一般而言,在子函数内,要想改变传进来的参数(全局变量)的值,必须要用到指针。

  • 比如 int a = 0,子函数应该这样写:xxxx(int *a),表示传进来的参数类型为指针类型,并且在子函数内部,单一个 (a) 表示的是 (原a)的地址,(*a)才是原来的(a),❗(*a)才等于0,要想改变(原a) 的值,对 (*a)❗重新赋值即可。(注意区分:①&为取址运算符,②为指针类型标识符。)

  • 对于指针同理,这里以指向链表第一个结点的指针L为例。当新元素插入位置位于链表开头时,需要将指针L重新指向新结点,即需要改变L所指向的值。L原本就是一个指针,对指针取值,子函数参数里要写成 **L,这里L是LinkList类型的指针变量,所以在参数里写成(*L)即可。同理,在函数内部,在未改变L所指向的值时,(*L)的值才是第一个结点的地址,想改变L所指向的值,对❗(*L)重新赋值即可。

#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>
#define error -1;
#define OK 1;

typedef int ElemType;
typedef int status;

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode, *LinkList;


LinkList creat()
{//使用尾插法建表;
    LinkList L;
//    L = (LinkList)malloc(sizeof(LNode));
//    if(!L)   printf("memory malloc error!\n");
//    LinkList p = L;
    ElemType a;
    int len;
    
    printf("请输入待建表的表长:");
    scanf("%d", &len);
    if(len>1)
    {
        printf("请输入第1个元素的值:");
        scanf("%d", &a);
        L = (LinkList)malloc(sizeof(LNode));
        if(!L)   
            printf("memory malloc error!\n");
        L->data = a;
        LinkList p = L;
        
        for(int i=1; i<len; i++)
        {   
            printf("请输入第%d个元素的值:", i+1);
            scanf("%d", &a);
            p->next = (LinkList)malloc(sizeof(LNode));
            p->next->data = a;
            p = p->next;
    }
    
    p->next = NULL;
    
    return L;
    }
    
}

void print(LinkList L)
{
    LinkList p = L;
    while(p != NULL)
    {
        printf("%d\n", p->data);
        p = p->next;
    }
}

status insert(LinkList *L, int i, int b)    
{//这里形参取的是指向指针L的指针,即L的地址,*在这里表示指针类型
//因为有可能要改变指针L的值,即改变L的指向
    LinkList p = NULL;
    if (i<1)     return error;
    
    if (i == 1)
    { 
        p = (LinkList)malloc(sizeof(LNode));
        if(!p)   
            printf("memory malloc error!\n");
        p->data = b;
        p->next = *L;   //注意这里!!!*L才是原L,*的意思是【取】指针所指向的值
                        //此时L是原L的地址,想要取/改变原L的值,用*L
        *L = p;         //改变原L的指向,就用*L
        
        return OK;
    }
    else
    {
        p = (LinkList)malloc(sizeof(LNode));
        if(!p)   
            printf("memory malloc error!\n");
        p->data = b;
        
        LinkList q = *L;     //q用于查找插入位置
        LinkList qpre = NULL;   //qpre用于指向待插入位置的前一结点
        
        while(i>1)
        {
            qpre = q;
            q = q->next;
            i --;
        }//退出时,q指向待插入位置
        
        p->next = q;
        qpre->next = p;
        
        return OK;
    }
}



int main()
{
    LinkList L = creat();
    int i;
    printf("请输入待插入的位置:");
    scanf("%d", &i);
    int b;
    printf("请输入待插入的元素值:");
    scanf("%d", &b);
    
    insert(&L, i, b);       
//!!&取地址符,要将指针L的地址作为参数传进去,因为L所指向的值可能会发生改变
    
    print(L);
    
    return 0;
}
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值