我们在操作链表的时候,必须注意以下事项:
1. 链表指针为NULL的情况
2. 插入删除涉及到 链表第一个节点时,需要修改 链表的第一个节点:
a. 因为 c语言都是传值的,如果需要修改一个变量,就必须通过 指向该变量的指针(即该变量的地址)
例如:例如 修改 int a,则输入参数必须是 int* a, 修改a 则是: *a = b; (b为int)
我们需要修改一个指针时,就必须通过 该指针的地址,也就是 指向该指针的指针,即二级指针
例如 修改 int* a, 则输入参数必须是 int** a, 修改int*
a 则是 *a = b (b为int*)
这样的原因只有一个: C语言全都是值语义的,pass-by-value, 没有c++的引用语义 pass-by-reference
我们可以 传入指向链表的二级指针,注意区分 第一个节点操作 和 其后节点操作
的不同点
b. 我们可以 新建一个头节点,这个头节点指向 链表第一个节点,这样
链表节点的所有操作都可以 统一起来,而不需要区分 第一个节点和 其他节点
3. 涉及到 链表的插入操作时,需要注意的是 头插法 和
尾插法
4. 删除链表节点时,需要注意 free 节点内存
5. 操作链表时,时刻注意防止
断链 的情况,一般是 先保存一个temp,然后再 赋值
在链表的末尾中添加一个节点:
void AddToTail(ListNode** pHead, int value)
{
ListNode* pNew = new ListNode();
pNew->m_nValue = value;
pNew->m_pNext = NULL;if(*pHead == NULL)
{
*pHead = pNew;
}
else
{
ListNode* pNode = *pHead;
while(pNode->m_pNext != NULL)
pNode = pNode->m_pNext;pNode->m_pNext = pNew;
}
}
在链表中找到第一个含有某值的节点并删除该节点的代码:
void RemoveNode(ListNode** pHead, int value)
{
if(pHead == NULL || *pHead == NULL)
return;ListNode* pToBeDeleted = NULL;
if((*pHead)->m_nValue == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
}
else
{
ListNode* pNode = *pHead;
while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
pNode = pNode->m_pNext;if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
{
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
}
}if(pToBeDeleted != NULL)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
剑指offer (5) 链表插入删除