zoukankan      html  css  js  c++  java
  • Josephu问题的解决方案

    1. 问题描述:

        设编号为1,2,…,n的n个人围坐一圈,约定编号为k(1 <=k <=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    2. 分析: 该问题可以使用多种数据结构, 但是比较简单和自然的做法是利用一个具有n个链接点且不带头接点的循环链表.

    3. 实现:

      1) 建立循环链表:

    代码
        public class CirculaLinkedNode<T>
        {
            
    public T Data { setget; }
            
    public CirculaLinkedNode<T> Next { setget; }
        }

        
    public class CirculaLinkedList<T>
        {
            
    public CirculaLinkedNode<T> Head { setget; }

            
    public CirculaLinkedList(CirculaLinkedNode<T> head)
            {
                
    this.Head = head;
            }

            
    public CirculaLinkedList(T[] data)
            {
                
    if (data == null || data.Length < 1)
                {
                    
    throw new ArgumentNullException("data");
                }

                CirculaLinkedNode
    <T> head = new CirculaLinkedNode<T>
                {
                    Data 
    = data[0],
                    Next 
    = null
                };
                CirculaLinkedNode
    <T> currentNode = head, node = null;
                
    for (int i = 1; i < data.Length; i++)
                {
                    node 
    = new CirculaLinkedNode<T>
                    {
                        Data 
    = data[i],
                        Next 
    = null
                    };
                    currentNode.Next 
    = node;

                    currentNode 
    = node;
                }
                currentNode.Next 
    = head;

                
    this.Head = head;
            }

            
    public void Remove(CirculaLinkedNode<T> node)
            {
                
    if (this.Head == null)
                {
                    
    return;
                }

                
    if (this.Head.Equals(node))
                {
                    
    if (Head.Next.Equals(Head))
                    {
                        Head 
    = null;
                    }
                    
    else
                    {
                        var n 
    = Head.Next;
                        
    while (!n.Next.Equals(Head))
                        {
                            n 
    = n.Next;
                        }
                        n.Next 
    = Head.Next;
                        Head 
    = Head.Next;
                    }
                }
                
    else
                {
                    var n 
    = Head;
                    
    while (!n.Next.Equals(Head))
                    {
                        
    if (n.Next.Equals(node))
                        {
                            n.Next 
    = n.Next.Next;
                            
    break;
                        }

                        n 
    = n.Next;
                    }
                }            
            }

            
    public CirculaLinkedNode<T> GetNodeByValue(T value)
            {
                var node 
    = this.Head;
                
    while (!node.Next.Equals(Head))
                {
                    
    if (node.Data.Equals(value))
                    {
                        
    return node;
                    }

                    node 
    = node.Next;
                }

                
    return null;
            }
        }

       2) 实现Josephu解决方案:

    代码
            /// <summary>
            
    /// Josephy Problem
            
    /// </summary>
            
    /// <param name="n">N people</param>
            
    /// <param name="m"></param>
            
    /// <param name="k"></param>
            public static void Josephu(int n, int m, int k)
            {
                
    if (n < 1)
                {
                    
    throw new ArgumentOutOfRangeException("n");
                }
                
    if (m < 1)
                {
                    
    throw new ArgumentOutOfRangeException("m");
                }
                
    if (k < 1 || k > n)
                {
                    
    throw new ArgumentOutOfRangeException("k");
                }

                
    int[] personArray = new int[n];
                
    for (int i = 0; i < n; i++)
                {
                    personArray[i] 
    = i + 1;
                }

                CirculaLinkedList
    <int> cList = new CirculaLinkedList<int>(personArray);
                var firstNode 
    = cList.GetNodeByValue(k);
                var node 
    = firstNode;
                
    while (cList != null && cList.Head != null)
                {
                    
    for (int i = 1; i < m; i++)
                    {
                        node 
    = node.Next;
                    }
                    Console.Write(
    "---> {0}", node.Data);
                    firstNode 
    = node.Next;
                    cList.Remove(node);
                    node 
    = firstNode;
                }
                Console.WriteLine(
    "");
            }

        3) 测试:

    CirculaLinkedListAction.Josephu(843);

     download


     

  • 相关阅读:
    16. 3Sum Closest
    17. Letter Combinations of a Phone Number
    20. Valid Parentheses
    77. Combinations
    80. Remove Duplicates from Sorted Array II
    82. Remove Duplicates from Sorted List II
    88. Merge Sorted Array
    257. Binary Tree Paths
    225. Implement Stack using Queues
    113. Path Sum II
  • 原文地址:https://www.cnblogs.com/Langzi127/p/1773583.html
Copyright © 2011-2022 走看看