您的位置:首页 > 职场人生

链表面试题(一)

2016-06-14 13:47 330 查看
在前边的博客中,我已经整理了链表的基本操作,在这篇文章,我来整理关于链表的一部

分面试题:

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: