数据结构_题目

数据结构

今天笔者出去面试,遇到了两个面试题,是非常基础的数据结构方面的,分享给大家。

老师带着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 国际许可协议进行许可。

posted @ 2018-03-02 23:11  繁星陨辰  阅读(189)  评论(0编辑  收藏  举报