文章目录
1.链表的基本实现
https://blog.csdn.net/weixin_41892460/article/details/82855823
2.删除指定位置的节点
void Erase(pList * pplist, pNode pos)
{
assert(pplist != NULL);
assert(pos != NULL);
if (*pplist == pos)//如果指向第一个节点
{
pNode del = pos;
*pplist = (*pplist)->next;
free(del);
del = NULL;
}
else
{
pNode cur = *pplist;
while (cur && cur->next != pos)//此处要找到pos的前一个节点,由于要将pos节点free前,
//必须将pos的前一节点和后一节点连起来,所以此处不用cur!=pos作为条件
{
cur = cur->next;
}
if (cur != NULL)
{
cur->next = pos->next;
free(pos);
pos = NULL;
}
}
}
void TestErase()
{
Node* plist = NULL;//指向第一个节点的指针
pNode pos = NULL;
PushFront(&plist, 1);
PushFront(&plist, 2);
PushFront(&plist, 3);
PushFront(&plist, 4);
PrintLinkList(plist);
pos = Find(plist, 2);
if (pos != NULL)
{
Erase(&plist, pos);
}
PrintLinkList(plist);
DestroyLinkList(&plist);
}
3.删除一个不是尾节点的节点
void EraseNotTailNode(pNode pos)
{
pNode del = NULL;
assert(pos);
assert(pos->next);
//
del = pos->next;
pos->data = pos->next->data;
//
pos->next = del->next;
free(del);
del = NULL;
}
void TestEraseNotNode()
{
Node* plist = NULL;//指向第一个节点的指针
pNode pos = NULL;
PushFront(&plist, 1);
PushFront(&plist, 2);
PushFront(&plist, 3);
PushFront(&plist, 4);
PrintLinkList(plist);
pos = Find(plist, 3);
if (pos != NULL)
{
EraseNotTailNode(pos);
}
PrintLinkList(plist);
DestroyLinkList(&plist);
}
4.删除指定值的节点
void Remove(pList* pplist, DataType d)
{
pNode cur = NULL;
pNode prev = NULL;
assert(pplist);
cur = *pplist;
while (cur)
{
if (cur->data == d)
{
//第一个节点
if (*pplist == cur)
{
{
*pplist = cur->next;
free(cur);
cur = NULL;
}
}
else
{
prev->next = cur->next;
free(cur);
cur = NULL;
}
}
else
{
prev = cur;
cur = cur->next;
}
}
}
void TestRemove()
{
Node* plist = NULL;//指向第一个节点的指针
pNode pos = NULL;
PushBack(&plist, 3);
PushBack(&plist, 1);
PushBack(&plist, 3);
PushBack(&plist, 3);
PrintLinkList(plist);
Remove(&plist, 1);
PrintLinkList(plist);
}
5.删除所有的指定值
void RemoveAll(pList * pplist, DataType d)
{
pNode cur = NULL;
pNode prev = NULL;
cur = *pplist;
assert(pplist != NULL);
while (cur)
{
if (cur->data == d)//找到了
{
if (*pplist == cur)//第一个节点
{
*pplist = cur->next;
free(cur);
cur = *pplist;
}
else//不是第一个节点
{
prev->next = cur->next;
free(cur);
cur = prev;
}
}
else
{
prev = cur;
cur = cur->next;
}
}
}
6.在指定位置之前插入一个数值
void Insert(pList * pplist, pNode pos, DataType d)
{
pNode newNode = NULL;
assert(pplist != NULL);
assert(*pplist != NULL);
assert(pos != NULL);
if (pos == *pplist)
{
newNode = BuyNode(d);
newNode->next = *pplist;
*pplist = newNode;
}
else
{
pNode cur = *pplist;
while (cur && cur->next != pos)
{
cur = cur->next;
}
if (cur != NULL)
{
newNode = BuyNode(d);
newNode->next = pos;
cur->next = newNode;
}
}
}
void TestInsert()
{
Node* plist = NULL;//指向第一个节点的指针
pNode pos = NULL;
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PrintLinkList(plist);
pos = Find(plist, 2);
if (pos != NULL)
{
Insert(&plist, pos, 8);
}
PrintLinkList(plist);
DestroyLinkList(&plist);
}
7.由尾至头的打印节点
void PrintTailToHead(pList plist)
{
pNode tail = NULL;
pNode cur = plist;
pNode prev = NULL;
if (plist == NULL)
{
return;
}
while (cur)
{
tail = cur;
cur = cur->next;
}
while (tail != plist)
{
cur = plist;
while (cur != tail)
{
prev = cur;
cur = cur->next;
}
printf("%d->", tail->data);
tail = prev;
}
printf("%d->NULL\n", tail->data);
}
8.查找单链表的中间节点,要求只能遍历一次链表
思路:定义两个节点:一个走两步,一个走一步
void FindMidNode(pList* pplist)
{
pNode fast = *pplist;
pNode slow = *pplist;
if (NULL == *pplist)
{
printf("该链表为空");
}
else if (NULL == slow->next)
{
printf("%d ", slow->data);
}
else
{
while (fast->next&&fast)
{
fast = fast->next->next;
slow = slow->next;
}
printf("%d ", slow->data);
}
}
9.查找单链表的倒数第k个节点,要求只能遍历一次链表
思路:一个节点先走k步
void FindLastKNode(pList *pplist, int k)
{
pNode fast = *pplist;
pNode slow = *pplist;
if (NULL == *pplist || k <= 0)
{
printf("该链表为空");
}
while (k--)
{
fast = fast->next;
}
while (fast)
{
fast = fast->next;
slow = slow->next;
}
printf("%d ", slow->data);
}