链表由一系列不必在内存中相连的结构组成,每一个结构均含有表元素和指向包含该元素后继元的结构指针。最后一个元素的后继指针指向NULL。
该结构(又称为结点)由两个域组成:数据域和指针域,数据域存储数据元素信息,指针域存储后继结点的地址。
链表的实现
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
面试题一:输入一个头结点,从尾到头反过来打印出每个结点的值
//可以用栈来实现,,每经过一个结点的时候,把该结点放到一个栈中
//遍历完整个链表的时候再从栈顶开始逐个输出结点的值
void printReverseList(LinkList phead)
{
if(phead==NULL)
return;
stack<LinkList>nodes;
LinkList pnode=phead;
while(pnode!=NULL)
{
nodes.push(pnode);
pnode=pnode->next;
}
while(!nodes.empty())
{
pnode=nodes.top();
printf("%d\t",pnode->data);
nodes.pop();
}
}
面试题二:链表中倒数第K个结点
//设置两个指针,一前一后,先让前面那个指针移动K步
//然后连个指针同时移动,当前面那个指针移动到末尾的时候
//后面的指正正好指向倒数第K个结点
LinkList findKthNode(LinkList phead,int k)
{
if(LinkList==NULL&&k==0)
return NULL;
LinkList pAhead=phead;
LinkList pBehind=phead;
if(int i=0;i<k-1;++i)
{
if(pAhead->next!=NULL)
pAhead=pAhead->next;
else
return NULL;
}
while(pAhead->next!=NULL)
{
pAhead=pAhead->next;
pBehind=pBehind->next;
}
return pBehind;
}
类似的还有求一个链表的中间结点,判断一个单向链表是否有环;
//找出链表的中间结点且当中间结点有两个时取第一个;
LinkList findMiddle(LinkList list)
{
LinkList temp=list->next;
if(NULL==temp)
return NULL;
LinkList pHead=list->next;
while(pHead->next!=NULL&&pHead->next->next!=NULL)
{
pHead=pHead->next->next;
temp=temp->next;
}
return temp;
}
面试题三:反转链表
LinkList reverseList(LinkList head)
{
LinkList reversehead=NULL;
LinkList node=head->next;
LinkList pre=NULL;//保存当前结点的前一个结点;
while(node!=NULL)
{
LinkList pNext = node->next;
if(pNext==NULL)
reversehead=node;
node->next=pre;
pre=node;
node=pNext;
}
return reversehead;
}
面试题四:合并两个已经排序好的链表(递归实现)
LinkList mergeList(LinkList headA,LinkList headB)
{
if(NULL==headA)
return headB;
if(NULL==headB)
return headA;
LinkList mergeHead=NULL;
if(headA->data<headB->data)
{
mergeHead=headA;
mergeHead->next = mergeList(headA->next,headB);
}
else
{
mergeHead=headB;
mergeHead->next = mergeList(headA,headB->next);
}
return mergeHead;
}
面试题五 约瑟夫环(循环链表)
在1,2......n的n个数字中每次删除第m个数字,求最后剩下的数字是多少
//每次删除第m个元素
int lastRemaining(int n,int m)
{
LinkList list=creatCircle(n);
LinkList node=list;
LinkList p=list;
while(node!=node->next)
{
for(int i=1;i<=m-2;i++)
{
node=node->next;
}
//删除第m个元素;
LinkList deleteNode = node->next;
node->next=deleteNode->next;
free(deleteNode);
node=node->next;
}
return node->data;
}
//创建约瑟夫环
LinkList creatCircle(int nNode)
{
LinkList head,node;
head = (LinkList)malloc(sizeof(LNode));
node=head;
for(int i=1;i<=nNode;i++)
{
LinkList temp = (LinkList)malloc(sizeof(LNode));
temp->data=i;
node->next=temp;
node=temp;
}
node->next=head->next;//循环链表队尾指针指向头指针
free(head);
return node->next;
}