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

【面试题】单链表的操作1

2016-01-19 10:47 253 查看
单链表的建立、插入等替他操作见本人博客:
单链表的基本操作 http://10741357.blog.51cto.com/10731357/1736387
【面试题】单链表的操作2 http://10741357.blog.51cto.com/10731357/1736403
介绍了6种有关单链表的面试题,对于以下链表要求的实现,解题的思路很重要。
各函数的实现,代码如下:
#include"SListNode.h"

void PrintTailToHead(SListNode* pHead)//从尾到头打印单链表
{//递归实现
if (pHead)
{
PrintTailToHead(pHead->next);
printf("%d->", pHead->data);
}
}
void DelNonTailNode(SListNode* pos)//删除一个无头单链表的非尾节点(删除pos节点)
{//替换法
//1->2->3->4删除第2个节点时,将第三个节点值赋给第二个1->3->2->4,删除第3个节点
assert(pos);
assert(pos->next);
SListNode* del = pos->next;
SListNode* next = del->next;//pos->next->next
pos->data = del->data;
pos->next = next;
free(del);
}
void InsertFrontNode(SListNode* pos, DataType x)//在无头单链表的一个非头结点前插入一个节点
{//替换法
//1->2->4->5第三个节点4前插入3,则4、5间插入3(1->2->4->3->5),再互换第三、四个节点值
assert(pos);
SListNode* tmp = _BuyNode(pos->data);
tmp->next = pos->next;
pos->next = tmp;//1->2->4->4->5
tmp->data = x;
//SListNode* tmp = _BuyNode(x);
//tmp->next = pos->next;
//pos->next = tmp;
//DataType temp = pos->data;
//pos->data = tmp->data;
//tmp->data = temp;
}
SListNode* Rverse(SListNode* pHead)//逆置/反转单链表
{//头插思想,注意反转要检查该单链表是否为空
//1->2->3->4新链表中依次取出1 2 3 4进行头插
if (pHead == NULL)
{
printf("SListNode is NULL!\n");
return NULL;
}
SListNode* newHead = NULL;
SListNode* cur = pHead;
while (cur)
{
SListNode* tmp = cur;
cur = cur->next;
tmp->next = newHead;
newHead = tmp;
}
return newHead;
}
SListNode* FindMidNode(SListNode* pHead)//查找单链表的中间节点,要求只能遍历一次链表
{//利用快慢指针实现,快指针走2步的是慢指针走1步的2倍
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast && fast->next)
{
fast = fast->next->next;
//链表总数为偶数时加上if返回较小数,无if时返回较大数
if (fast == NULL)
break;
slow = slow->next;
}
//while (fast)
//{
//	if(fast->next)
//		fast = fast->next->next;
//	else break;
//	slow = slow->next;
//}
return slow;
}
SListNode* FindMidNode(SListNode* pHead, DataType k)//查找单链表的倒数第k个节点,要求只能遍历一次链表
{//快慢指针,快指针走k步,慢指针走一步,之后同速度走
SListNode* fast = pHead;
SListNode* slow = pHead;
while (k-- && fast)
fast = fast->next;
if (k == -1)
{
while (fast)
{
slow = slow->next;
fast = fast->next;
}
}
else
return NULL;
//while (k-- && fast)
//{
//	fast = fast->next;
//	if (fast == NULL)
//		return NULL;
//}
//while (fast)
//{
//	slow = slow->next;
//	fast = fast->next;
//}
return slow;
}
各函数测试用例如下:
void Test4()
{//【面试题一】从尾到头打印单链表
SListNode *phead = NULL;
PushBack_Cpp(phead, 1);
PushBack_Cpp(phead, 2);
PushBack_Cpp(phead, 3);
PushBack_Cpp(phead, 4);
PushBack_Cpp(phead, 5);
PushBack_Cpp(phead, 6);
PrintSList(phead);
printf("\n---------------------\n");
PrintTailToHead(phead);
printf("NULL");
}

void Test5()
{//【面试题二】删除一个无头单链表的非尾节点
SListNode *phead = NULL;
PushBack_Cpp(phead, 1);
PushBack_Cpp(phead, 2);
PushBack_Cpp(phead, 3);
PushBack_Cpp(phead, 8);
PushBack_Cpp(phead, 4);
PushBack_Cpp(phead, 5);
PrintSList(phead);
printf("\n---------------------\n");
DelNonTailNode(Find(phead, 8));
PrintSList(phead);
DestoryList(phead);
}

void Test6()
{//【面试题三】在无头单链表的一个非头结点前插入一个节点
SListNode *phead = NULL;
PushBack_Cpp(phead, 1);
PushBack_Cpp(phead, 2);
PushBack_Cpp(phead, 4);
PushBack_Cpp(phead, 5);
PushBack_Cpp(phead, 6);
PrintSList(phead);
printf("\n---------------------\n");
InsertFrontNode(Find(phead, 4), 3);
PrintSList(phead);
DestoryList(phead);
}

void Test7()
{//【面试题四】逆置/反转单链表
SListNode *phead = NULL;
PushBack_Cpp(phead, 1);
PushBack_Cpp(phead, 2);
PushBack_Cpp(phead, 3);
PushBack_Cpp(phead, 4);
PrintSList(phead);
printf("\n---------------------\n");
SListNode *newphead = Rverse(phead);
PrintSList(newphead);
DestoryList(phead);
}

void Test8()
{//【面试题五】查找单链表的中间节点,要求只能遍历一次链表
SListNode *phead = NULL;
PushBack_Cpp(phead, 2);
PushBack_Cpp(phead, 3);
PushBack_Cpp(phead, 4);
PushBack_Cpp(phead, 5);
PushBack_Cpp(phead, 6);
PushBack_Cpp(phead, 7);
PrintSList(phead);
printf("\n---------------------\n");
printf("%d\n",FindMidNode(phead)->data);
DestoryList(phead);
}

void Test9()
{//【面试题六】查找单链表的倒数第k个节点,要求只能遍历一次链表
SListNode *phead = NULL;
PushBack_Cpp(phead, 1);
PushBack_Cpp(phead, 2);
PushBack_Cpp(phead, 3);
PushBack_Cpp(phead, 5);
PushBack_Cpp(phead, 6);
PushBack_Cpp(phead, 7);
PrintSList(phead);
printf("\n---------------------\n");
SListNode *pos = FindMidNode(phead, 3);
printf("%d\n",pos->data);
DestoryList(phead);
}
int main()
{
Test4();
printf("\n***********************\n");
Test5();
printf("\n***********************\n");
Test6();
printf("\n***********************\n");
Test7();
printf("\n***********************\n");
Test8();
printf("\n***********************\n");
Test9();
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单链表 遍历 逆置