关于链表中的Insert与Delete中的细节

《大话数据结构》

先放上书中给出的标准代码:

/* 初始条件:链式线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList* L, int i, ElemType e)
{
	int j;
	LinkList p, s;
	p = *L;
	j = 1;
	while (p && j < i)     /* 寻找第i个结点 */
	{
		p = p->next;
		++j;
	}
	if (!p || j > i)
		return ERROR;   /* 第i个元素不存在 */
	s = (LinkList)malloc(sizeof(Node));  /*  生成新结点(C语言标准函数) */
	s->data = e;
	s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
	p->next = s;          /* 将s赋值给p的后继 */
	return OK;
}
/* 初始条件:链式线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(LinkList* L, int i, ElemType* e)
{
	int j;
	LinkList p, q;
	p = *L;
	j = 1;
	while (p->next && j < i)	/* 遍历寻找第i个元素 */
	{
		p = p->next;
		++j;
	}
	if (!(p->next) || j > i)
		return ERROR;           /* 第i个元素不存在 */
	q = p->next;
	p->next = q->next;			/* 将q的后继赋值给p的后继 */
	*e = q->data;               /* 将q结点中的数据给e */
	free(q);                    /* 让系统回收此结点,释放内存 */
	return OK;
}

要分析的问题有以下:

  • 为什么形式参数使用的是LinkList而不是LinkList*?
    • 先给出以下结构体定义。
typedef struct Node{
	ElemType data;
	struct Node* next;
}Node;
typedef struct Node* LinkList; /* 定义LinkList */
    • LinkList是一个结构体指针,之前书中提到过:
    • 在顺序表中这句话是完全没毛病的,因为SqList是一个结构体的别名(非指针);但在链表中LinkList是一个结构体指针,它是等于Node*,保存的数值是一个结构体的地址;根据上面这段话的意思,需要改动时就要传递LinkList的指针,也就是LinkList*,指针的指针,即二维指针**;所以,在LinkList和LinkDelete中,都是p=*L,需要解引用才能得到头节点(结构体)的地址;如果是p=L的话,得到的将会是一维指针的地址。
    • 在传参时,也需要注意的是要传入的是指针的地址&L
    • 但其实这是不太必要的,先传入&,然后再使用*,到头来使用的还是结构体的地址。
      可以直接传入L,接收时就不用写*,反正传的都是地址,对结果不会有什么影响。
  • 为什么p=*L,而不是让p=*L->next
    • 我对这个的理解是:有的时候虽然说要操作的是第i个元素,但是真正要寻找的是第i-1个元素(插入,删除等)。
    • 以LinkInsert举例:
      • 一开始的j=1,假如顺利的情况下,while循环结束的时候刚好j=i,此时p->data刚好是第i-1个元素。
  • 在这两个函数中,对链表为空的情况是怎么处理的?
    • 在ListInsert中,没有处理(本来也不需要处理)如果在链表为空的请款下,程序会跳过while循环(j==i),也会跳过if (!p || j > i)(p指向头节点,非空)。
    • 不过给出了前提条件
    • 所以压根就不用考虑空链表的问题。
      • 如果只是在原有的代码修改下,判空处理和让p指向第一个i-1个元素是不能同时实现的。
    • 但是在ListDelete中却可以实现判空处理,因为if (!p->next || j > i)条件中的是p->next,当遇到链表的情况时符合条件。
      • 为什么ListDelete不能使用if (!p->next || j > i)呢?
        • 如果要插入的是最后一个元素,也会被这个条件带走,但最后一个元素后面虽然是NULL,但也是可以插入的。
  • 在while循环中,为什么LinkInsert中使用的是p,而在LinkDelete中使用的确实p->next
    • 因为ListInsert中,要插入的第i个元素可以为NULL;但是在删除时要删除的第i个元素却不能为NULL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值