在前边的博客中,我已经整理了链表的基本操作,在这篇文章,我来整理关于链表的一部
分面试题:
1.删除无头指针的非尾节点
2.逆序链表
3.在当前节点前插入一个元素(不给出链表的头指针)
4.查找链表的中间节点
5.删除链表的倒数第k个结点
下边我一一给出解释(尽量画图),和对应的代码:
先给出下边代码要用到的结构体的声明:
typedef struct LinkNode
{
DataType data;
struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
LinkNode *pHead;
}LinkList,*pLinkList;
1.删除无头指针的非尾节点
代码:
//删除无头结点的非尾节点
void EarseNotTail(pLinkNode pos)
{
assert(pos && pos->next);
pLinkNode del = pos->next;
pos->data = pos->next->data;
pos->next = pos->next->next;
free(del);
}
测试用例:pos为当前链表的最后一个结点。
pos为当前链表的第一个结点。
2.逆序链表
//逆序链表
void Reverselist(pLinkList plist)
{
assert(plist);
pLinkNode cur = plist->pHead;
pLinkNode tmp = NULL;
pLinkNode newHead = NULL;
while (cur)
{
tmp = cur;
cur = cur->next;
tmp->next = newHead;
newHead = tmp;
}
plist->pHead = newHead;
}
3.在当前节点前插入一个元素(不给出链表的头指针)
由于这个比较简单,可以类比1,我们无法在pos前边插入元素,但是可以在后边插入,
完了把pos和pos的下一个位置的元素交换就好了~~
//在当前节点前插入一个元素(同样不给出链表的头指针)
void InsertFrontNode(pLinkNode pos, DataType x)
{
assert(pos);
pLinkNode newNode = CreatNode(x);
DataType tmp = 0;
newNode->next = pos->next;
pos->next = newNode;
tmp = pos->data;
pos->data = pos->next->data;
pos->next->data = tmp;
}
测试用例:pos为当前链表的第一个结点、最后一个结点、中间任意结点。三种情况都
应该测到。
4.查找链表的中间节点
代码:
//查找链表的中间节点
pLinkNode FindMidNode(pLinkList plist)
{
assert(plist);
pLinkNode fast = plist->pHead;
pLinkNode slow = plist->pHead;
while (fast&&fast->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
要是以奇数的判定条件还能判定偶数吗???当然是不可以的嘛。为什么我这样说呢!
以为一开始我写的代码,while里边只有一个条件fast->next,这是不对的。并且两个条
件之间逻辑与。(只要有一个条件不满足,循环就结束。)
测试用例:结点总数 为奇数;
结点总数为偶数。
5.删除链表的倒数第k个结点
//删除链表的倒数第k个结点
void DelKNode(pLinkList plist, DataType k)
{
assert(plist);
assert(k > 1);
if (plist->pHead == NULL)
{
return;
}
pLinkNode front = plist->pHead;
pLinkNode back = plist->pHead;
pLinkNode del = plist->pHead;
while (front)
{
k--;
if (k < 0)
{
back = back->next;
}
front = front->next;
}
if (k <= 0)
{
back->data = back->next ->data;
del = back->next;
back->next = back->next->next;
free(del);
}
}
测试用例:k = 1时assert不通过,报错。
k = 5(假设链表总共5个结点)会正常删除
k = 3。
这些都要测试到。
注意:不要总是一遇到特殊情况就特殊处理~~不然代码全是特殊处理~
测试函数:
void test2()
{
LinkList list;
pLinkNode pos = NULL;
//pLinkNode ret = NULL;
InitLinkList(&list);
PushBackLinkList(&list, 1);
PushBackLinkList(&list, 2);
PushBackLinkList(&list, 3);
PushBackLinkList(&list, 4);
PushBackLinkList(&list, 5);
PrintLinkList(&list);
//测试删除
/*pos = find(&list, 4);
EarseNotTail(pos);*/
//测试逆序
//Reverselist(&list);
//测试插入函数
/*pos = find(&list,5);
InsertFrontNode(pos, 7);*/
pos = FindMidNode(&list);
printf("%d",pos->data);
//PrintLinkList(&list);
DelKNode(&list, 1);
PrintLinkList(&list);
DestroyLinkList(&list);
}