一个排序的链表中删除重复的数据
注意下面几点
边界条件控制指向头节点的指针为nullptr
重复数据位于链接中间 最简单的情况正常秩序就OK
重复数据位于头部。改变头指针的指向。执行此时的next节点
重复数据位于尾部。pPre->next = nullptr;
链接数据都是重复的。情况链表
C++ 野指针崩溃
void deleteDuplication(ListNode**pHeader){
if (pHeader == nullptr ||*pHeader == nullptr) {
return;
}
ListNode*pPreNode = nullptr;
ListNode*pNode = *pHeader;
while (pNode != nullptr) {
ListNode*pNextNode = pNode->m_pNext;
bool needDelete = false;
if (pNextNode!=nullptr&&pNextNode->m_nValue == pNode->m_nValue) {
needDelete =true;
}
if (!needDelete) {
pPreNode = pNode;
pNode = pNextNode;
}
else{
ListNode*pDeleteNode = pNode;
int value = pDeleteNode->m_nValue;
while (pDeleteNode != nullptr && pDeleteNode->m_nValue == value) {
pNextNode = pDeleteNode->m_pNext;
delete pDeleteNode;
pDeleteNode = nullptr;
pDeleteNode = pNextNode;
}
if (pPreNode == nullptr) {
*pHeader = pNextNode;
}else{
pPreNode->m_pNext = pNextNode;
}
pNode = pNextNode;
}
}
}
题目中的排序为我们解决了很大的困扰,排序说明重复的元素是挨着的。
下面解释下上面的几点注意。
写函数先考虑边界条件的控制。如果头指针为空,或者指针本身为空直接返回。
重复数据位于中间的话正常执行删除操作,让pPreNode->next = pNext;这样直接把重复的节点过滤掉了
重复数据位于头部
if (pPreNode == nullptr) *pHeader = pNextNode;
改变头指针。执行下一次循环的时候因为肯定不是重复的,那么pPreNode = pNode。这样*pHeader和pPreNode就对上了。重复数据位于尾部
pPreNode->m_pNext = pNextNode;
。pPreNode ->m_pNext== nullptr 过滤掉其他的。使pPreNode成为尾部先判断
pNextNode!=nullptr
只有这个指针存在才可以使用它执行的node的内容。防止发生野指针异常引发的崩溃。链表如果是重复的 会直接走到最后
*pHeader = pNextNode
。头指针为空,全部删完。