【应聘笔记系列】三个常见链表笔试题

链表是经常应聘时经常考察的重要数据结构,今日复习了一下并就几个几个代表性问题上机调试了一下程序。

1、  单链表问题

Ø         单链表的反转:这个问题似乎在面试和笔试中特别受宠,屡屡出现.

解决方法:用三个指针。代码如下:

node *reverse(node *head) { node *p1,p2,p3; if(head==NULL || head->next==NULL) return head; p1=head; p2=head->next; while (p2) { p3=p2->next; p2->next=p1; p1=p2; p2=p3; } head->next=NULL; head=p1; return head; }

 

Ø         给出一个单链表,不知道节点N的值,遍历一次求出中间节点。

解决方法:设立两个指针,一个指针每次移动两个位置,另外一个指针每次移动一个位置,当第一个指针移动到最后时,后面的指针所指的位置就是中间位置。

void searchMid(node *head,node *mid) { node *temp1,temp2; temp1=head; temp2=head; while (temp2->next->next!=null) { temp2=temp2->next->next; temp1=temp1->next; mid = temp1; } }

 

Ø         循环链表问题:循环链表有个典型应用就是解约瑟夫问题(Josephus),这里用的典型题目是"猴子选大王"n只猴子要选大王,选举方法如下:所有猴子按 12 ……… n 编号并按照顺序围成一圈,从第 k 个猴子起,由1开始报数,报到m时,该猴子就跳出圈外,下一只猴子再次由1开始报数,如此循环,直到圈内剩下一只猴子时,这只猴子就是大王。

输入数据为猴子总数n,起始报数的猴子编号k,出局数字m。输出数据为猴子初队序列和猴子大王的编号。

解决方法:建立一个有n个节点,没有头结点的循环链表,确定第一个报数人的位置。不断从链表中删除节点,直到链表为空。

#include "stdafx.h" #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node *next; }LNode; //总数n,起始报数的编号k,出局数字m void Josephus(int n,int k,int m) { int i; int totle = n; LNode *p,*prevP,*head,*s;//p为当前节点,head为头节点 head=(LNode *)malloc(sizeof(LNode)); head->data = 0; head->next = head; p = head; p->data = 1; p->next = p; for(i=2;i<=n;i++) { LNode * temp = (LNode *)malloc(sizeof(LNode)); temp->data = i; temp->next = p->next; p->next = temp; p=p->next; } p = head; for(i=1;i<k;i++) p=p->next; prevP = head; while(totle!=1) { for(i=1;i<m;i++) p=p->next; printf("%d 出局/n",p->data); while(prevP->next!=p) prevP=prevP->next; prevP->next = p->next; s = p; p = p->next; free(s); totle--; } printf("最后剩下的节点为%d",p->data); } int main() { Josephus(13,4,1); return 0; }

 

 

 

你可能感兴趣的:(数据结构,面试,struct,null,p2p)