数据结构_题目
数据结构
今天笔者出去面试,遇到了两个面试题,是非常基础的数据结构方面的,分享给大家。
老师带着100个学生出去郊游,到了目的地后老师提出玩一个游戏,大家围成一个圈,让学生们按1,2,3,4,5...;当数到9的时候这个学生要出来表演节目,表演完之后要从下一个继续数数,求输出表演的学生。(任一语言皆可)
思路:其实这个问题就是约瑟夫问题,我们可以运用单向循环链表实现;
实现:
using System;
namespace 约瑟夫问题
{
class CircularLinkedList
{
//成员
private int count;//记录元素个数
private Node tail;//尾指针
private Node currentPrev;//使用前驱结点来标识结点
//方法
//在链表结尾添加元素
public void Add(object value)
{
Node newNode = new Node(value);
if (tail == null)
{
//如果链表为空则新元素即是尾指针也是头指针
tail = newNode;
tail.next = newNode;
currentPrev = newNode;
}
else
{
//否则插入到链表的结尾
//新结点的指针域指向头结点
newNode.next = tail.next;
tail.next = newNode;
if (currentPrev == tail)
{
currentPrev = newNode;
}
//把尾指针指向新结点
tail = newNode;
}
count++;
}
//删除当前结点
public void RemoveCurrentNode()
{
//如果为空表
if (tail == null)
{
throw new NullReferenceException("集合中没有任何元素");
}
else if (count == 1)
{
//当只有一个元素的时候,删除后为空
tail = null;
currentPrev = null;
}
else
{
if (currentPrev.next == tail)
{
//当删除的是尾指针所指向的结点时
tail = currentPrev;
}
currentPrev.next = currentPrev.next.next;
}
count--;
}
//让所有结点向前移动指定步骤
public void Move(int step)
{
if (step < 0)
{
throw new ArgumentOutOfRangeException("step", "移动步数不能小于零");
}
//如果为空表
if (tail == null)
{
throw new NullReferenceException("集合中没有元素");
}
//移动指针
for (int i = 0; i < step; i++)
{
currentPrev = currentPrev.next;
}
}
//打印整个链表
public override string ToString()
{
if (tail == null)
{
return string.Empty;
}
string s = " ";
Node temp = tail.next;
for (int i = 0; i < count; i++)
{
s += temp.ToString() + " ";
temp = temp.next;
}
return s;
}
//属性
//指示链表中的元素个数
public int Count
{
get { return this.count; }
}
//指示当前结点中的值
public object Current
{
get { return currentPrev.next.item; }
}
//嵌套类,表示单个结点
class Node
{
public object item;//数据域
public CircularLinkedList.Node next;//指针域,指向后继节点
public Node(object value)
{
item = value;
}
public override string ToString()
{
return item.ToString();
}
}
}
}
调用测试:
static void Main(string[] args)
{
CircularLinkedList cList = new CircularLinkedList();
Console.WriteLine("请输入学生人数:");
int studentNum = int.Parse(Console.ReadLine());
Console.WriteLine("请输入要出链表的数:");
int m = int.Parse(Console.ReadLine());
Console.WriteLine("游戏开始!");
string s = string.Empty;
for (int i = 0; i < studentNum; i++)
{
cList.Add(i);
}
Console.Write("所有的人:" + cList.ToString());
while (cList.Count > 1)
{
cList.Move(m);//数数
s += cList.Current.ToString() + " ";
cList.RemoveCurrentNode();//出队
}
Console.WriteLine("\r\n出队顺序:" + s + cList.Current);
}
运行效果:
本作品由繁星陨辰采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。