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

链表面试题

2016-05-26 12:28 363 查看
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<assert.h>
typedef int DataType;
typedef struct SListNode
{
DataType data;
struct SListNode *next;
}SListNode;
void PrintFromEndToTail(SListNode * &Head);// 从尾到头打印。
void SListNodeReverse(SListNode *& Head);
void Joseph(SListNode *&Head, DataType k);
SListNode *Find(SListNode *Head, DataType x);
void PushBack(SListNode * & Head);//尾插
SListNode *BuyNode(DataType x);
void PrintSListNode(SListNode *Head);
void BubbleSort(SListNode *&Head);  //单链表排序(冒泡)
SListNode *MergeList(SListNode *&Head1, SListNode *&Head2);//合并两个有序列表,合并后依然有序
//判断单链表是否带环?若带环求环长度?求环得入口点?并计算每个算法的时间复杂度和空间复杂度。
SListNode *CycleOrNot(SListNode *Head);
int CycleLength(SListNode *meeting);
SListNode *Entrance(SListNode *Head,DataType length);
SListNode *FindCrossingNode(SListNode *Head1, SListNode *Head2);//判断两个链表是否相交,若相交,求交点(带环)
int GetNodeCountOfList(SListNode *Head);
SListNode *FindCycleEntry(SListNode Head);
SListNode *FindLoopPort(SListNode *Head1, SListNode *Head2);//判断两个链表是否相交,若相交,求交点(不带环)
//复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随即节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
SListNode *BuyNode(DataType x)
{
SListNode *tmp = (SListNode*)malloc(sizeof(SListNode));
tmp->data = x;
tmp->next = NULL;
return tmp;
}
SListNode *Find(SListNode *Head, DataType x)
{
assert(Head);
SListNode *cur = Head;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void PushBack(SListNode * & Head,DataType x)
{
if (Head == NULL)
{
Head = BuyNode(x);
}
else if (Head->next == NULL)
{
Head->next = BuyNode(x);
}
else
{
SListNode *tail = Head;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = BuyNode(x);
}
}
void PrintSListNode(SListNode *Head)
{
if (Head == NULL)
{
return;
}
else
{
while (Head)
{
printf("%d ", Head->data);
Head = Head->next;
}
}
}
void PrintFromEndToTail(SListNode * &Head) // 从尾到头打印。
{
if (Head != NULL)
{
PrintFromEndToTail(Head->next);
printf("%d ", Head->data);
}
}
// 在无头链表的一个非头节点前插入一个节点
void InsertUheadPrev(SListNode * pos,DataType x)// 在无头链表的一个非头节点前插入一个节点
{
assert(pos);
SListNode * tmp = BuyNode(pos->data);
SListNode *tmp2 = pos->next;
pos->data = x;
pos->next = tmp;
tmp->next = tmp2;
}
//查找单链表的中间节点,要求只遍历一遍
SListNode *FindMidNode(SListNode *Head)
{
int i = 0;
SListNode *fast = Head;
SListNode *slow = Head;
while (fast)
{
if (fast->next != NULL)
{
fast = fast->next->next;
}
else
{
return slow;
}
slow = slow->next;
}
return slow;
}
//查找单链表的倒数第K个节点,要求只遍历一遍
SListNode *FindKNode(SListNode *Head, DataType k)
{
int i = 0;
SListNode *fast = Head;
SListNode *slow = Head;
for (i = 0; i < k; i++)
{
fast = fast->next;
if (fast == NULL)
{
return NULL;
}
}
while (fast)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
//逆置或反转单链表
void SListNodeReverse(SListNode *& Head)
{
SListNode *pNode = Head;
SListNode *Prev = NULL;
SListNode *pNext = NULL;
while ( pNode)
{
pNext = pNode->next;
if (pNext)
{
Head = pNode->next;
}
pNode->next = Prev;
Prev = pNode;
pNode = pNext;
}
}
// 删除一个无头链表的非尾节点
void SListDel(SListNode *&del)
{
SListNode *tmp = del->next->next;
del->data = del->next->data;
del->next = tmp;
free(del->next);
}
void Joseph(SListNode *&Head, int k)
{
assert(Head);
SListNode* cur = Head;
SListNode *del = NULL;
while (1)
{
if (cur->next == cur)
{
printf("%d", cur->data);
return;
}
for (int i = 1; i < k; i++)
{
cur = cur->next;
}
del = cur->next;
cur->data = cur->next->data;
cur->next = del->next;
free(del);
}
}
void BubbleSort(SListNode *&Head)  //冒泡排序
{
SListNode *tail = NULL;
while (Head->next != tail)
{ int flag = 0;
SListNode *cur = Head;
SListNode *CurNext = cur->next;
while (cur->next!=tail)
{
if (cur->data > CurNext->data)
{
DataType tmp = cur->data;
cur->data = CurNext->data;
CurNext->data = tmp;
flag = 1;
}
cur = cur->next;
CurNext = CurNext->next;
}
tail = cur;
if (flag == 0)
{
return;
}
}
}
SListNode *MergeList(SListNode *&Head1, SListNode *&Head2)   //合并两个有序列表,合并后依然有序
{
SListNode *cur1 = Head1;
SListNode *cur2 = Head2;
SListNode *tmp = NULL;
SListNode *NewHead = NULL;
if (cur1->data > cur2->data)
{
NewHead = cur2;
cur2 = cur2->next;
}
else
{
NewHead = cur1;
cur1 = cur1->next;
}
tmp = NewHead;
while (cur1 && cur2)
{
if (cur1->data >= cur2->data)
{
tmp->next = cur2;
tmp = cur2;
cur2 = cur2->next;
}
else
{
tmp->next = cur1;
tmp = cur1;
cur1 = cur1->next;
}
}
if (cur1)
{
tmp->next = cur2;
return NewHead;
}
else
{
tmp->next = cur1;
return NewHead;
}
}

//判断单链表是否带环?若带环求环长度?求环得入口点?并计算每个算法的时间复杂度和空间复杂度。
SListNode *CycleOrNot(SListNode *Head)
{
assert(Head);
SListNode *fast = Head;
SListNode *slow = Head;
while (fast)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
printf("此单链表带环\n");
return fast;
}
}
return NULL;
}
int CycleLength(SListNode *meeting)
{
assert(meeting);
SListNode *tmp = meeting;
int count = 1;
while (1)
{
tmp = tmp->next;
if (tmp == meeting)
{
return count;
}
count++;
}
}
SListNode *Entrance(SListNode *Head, DataType length)
{
assert(Head);
SListNode *fast = Head;
SListNode *slow = Head;
while (length--)
{
fast = fast->next;
}
while (1)
{
fast = fast->next;
slow = slow->next;
if (fast == slow)
{
return fast;
}
}
return NULL;
}
SListNode *FindLoopPort(SListNode *Head1, SListNode *Head2)
{
assert(Head1);
assert(Head2);
SListNode *cur1 = Head1;
SListNode *cur2 = Head2;
SListNode *ret = NULL;
int length1 = 1;
int length2 = 1;
int count = 0;
int flag = 0;
while (cur1)
{
cur1 = cur1->next;
length1++;
}
while (cur2)
{
cur2 = cur2->next;
length2++;
}
if (cur1 != cur2)
{
printf("NO Port!\n");
return NULL;
}
else
{
if (length1 > length2)
{
count = length1 - length2;
flag = 1;
}
else
{
count = length2 - length1;
}
if (flag == 0)
{
cur1 = Head1;
cur2 = Head2;
while (count--)
{
cur2 = cur2->next;
}
while (cur1 && cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
if (cur1 == cur2)
{
return cur1;
}
}
}
else
{
cur1 = Head1;
cur2 = Head2;

while (count--)
{
cur1 = cur1->next;
}
while (cur1 && cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
if (cur1 == cur2)
{
return cur1;
}
}
}
}
return NULL;
}
//1、是否相交于环外,使用指针追赶的方法
//2、若不满足情况1,即不相交于环外,但两个链表又相交,则肯定相交于环内。
SListNode *FindCrossingNode(SListNode *Head1, SListNode *Head2)
{
assert(Head1);
assert(Head2);
SListNode *cur1 = Head1;
SListNode *cur2 = Head2;
int count1 = GetNodeCountOfList(Head1);
int count2 = GetNodeCountOfList(Head2);
SListNode *enter1 = FindCycleEntry(Head1);
SListNode *enter2 = FindCycleEntry(Head2);
while (count1 - count2 > 0)
{
cur1 = cur1->next;
count1--;
}
while (count2 - count1> 0)
{
cur2 = cur2->next;
count2--;
}
while (cur1 != enter1 && cur2 != enter2 && cur1 != cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
}
if (cur1 != cur2) //交点在环中
{
return enter1;
}
else   //交点在环内
{
return cur1;
}
}
//1、先找到碰撞点
//2、利用碰撞点,找到环入口点,同时统计第一个结点到碰撞点之间结点个数
//3、利用碰撞点或者环入口点,在环中转圈,统计环中结点个数
int GetNodeCountOfList(SListNode *Head)
{
assert(Head);
SListNode *fast = Head;
SListNode *slow = Head;
SListNode *enter = Head;
int CountEnter = 0;
int CountCycle = 1;
while (fast->next->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
{
while (enter != slow) //查找环的入口结点,并统计第一个结点到碰撞点之间结点个数
{
enter = enter->next;
slow = slow->next;
CountEnter++;
}
slow = fast;
fast = fast->next;
while (fast != slow)
{
fast = fast->next;
CountCycle++;
}
return CountCycle + CountEnter;
}
}
return 0;
}
/*在快慢指针相遇处,使用两个指针分别从头结点和碰撞处开始走,相遇点就是环入口点*/
SListNode *FindCycleEntry(SListNode *Head)
{
assert(Head);
SListNode* fast=Head;
SListNode *slow=Head;
SListNode *enter = Head;
while (1)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
while (slow != enter)
{
slow = slow->next;
enter = enter->next;
}
return enter;
}
}
return NULL;
}
void Test1()
{
SListNode *Head = NULL;
PushBack(Head, 1);
PushBack(Head, 2);
//PushBack(Head, 3);
//PushBack(Head, 4);
//PushBack(Head, 5);
PrintFromEndToTail(Head);
}
void Test2()
{
SListNode *Head = NULL;
PushBack(Head, 1);
PushBack(Head, 2);
PushBack(Head, 3);
PushBack(Head, 4);
PushBack(Head, 5);
SListNodeReverse(Head);
PrintSListNode(Head);
}
void Test3()  //约瑟夫环
{
SListNode *Head = NULL;
PushBack(Head, 1);
/*PushBack(Head, 2);*/
//PushBack(Head, 3);
//PushBack(Head, 4);
//PushBack(Head, 5);
//PushBack(Head, 6);
SListNode *tail = Find(Head, 1);
tail->next = Head;
Joseph(Head, 3);
}
void Test4()
{
SListNode *Head = NULL;
PushBack(Head, 1);
PushBack(Head, 4);
PushBack(Head, 5);
PushBack(Head, 3);
PushBack(Head, 2);
BubbleSort(Head);
PrintFromEndToTail(Head);
}
void Test5()
{
SListNode *Head1 = NULL;
SListNode *Head2 = NULL;
PushBack(Head1, 1);
PushBack(Head1, 3);
PushBack(Head1, 5);
PushBack(Head1, 7);
PushBack(Head1, 9);
PushBack(Head2, 2);
PushBack(Head2, 4);
PushBack(Head2, 6);
PushBack(Head2, 8);
PushBack(Head2, 10);
SListNode *NewHead=MergeList(Head1, Head2);
PrintSListNode(NewHead);
}
void Test6()   //带环问题
{
SListNode *Head = NULL;
PushBack(Head, 1);
PushBack(Head, 4);
PushBack(Head, 5);
PushBack(Head, 3);
PushBack(Head, 2);
PushBack(Head, 9);
PushBack(Head, 2);
PushBack(Head, 4);
PushBack(Head, 6);
SListNode *tmp1 = Find(Head, 9);
SListNode *tmp2=Find(Head, 6);
tmp2->next = tmp1;
SListNode *meeting=CycleOrNot(Head);
int length=CycleLength(meeting);
SListNode *ret=Entrance(Head, length);
printf("%d\n", ret->data);
printf("%d", length);
}
void Test7()
{
SListNode *Head1 = NULL;
SListNode *Head2 = NULL;
PushBack(Head1, 1);
PushBack(Head1, 3);
PushBack(Head1, 5);
PushBack(Head1, 7);
PushBack(Head1, 9);
PushBack(Head2, 2);
PushBack(Head2, 4);
PushBack(Head2, 6);
PushBack(Head2, 8);
PushBack(Head2, 10);
SListNode *tmp1 = Find(Head1, 5);
SListNode *tmp2 = Find(Head2, 10);
tmp2->next = tmp1;
SListNode *ret=FindLoopPort(Head1, Head2);
printf("%d", ret->data);
}
int main()
{
//Test1();
/*Test2();*/
/*Test3();*/
Test7();
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: