zoukankan      html  css  js  c++  java
  • 特殊排序之红白球

    特殊排序之红白球

    今天去面试,做了一道上机题,感觉有点意思,记录一下。
    设有红色、白色两种球若干,放在一个数组里,请实现算法:把红球排到白球前面。

    先设置好要操作的类:

    红白球Ball
     1     enum EBallColor
     2     {
     3         Red,
     4         White,
     5     }
     6     class Ball : IComparable<Ball>
     7     {
     8         public EBallColor BallColor { get; set; }
     9         public Ball(EBallColor color)
    10         {
    11             this.BallColor = color;
    12         }
    13         public override string ToString()
    14         {
    15             return string.Format("{0}", BallColor);
    16             //return base.ToString();
    17         }
    18 
    19         /// <summary>
    20         /// Red &gt; White
    21         /// </summary>
    22         /// <param name="other"></param>
    23         /// <returns></returns>
    24         public int CompareTo(Ball other)
    25         {
    26             if (other == null)
    27             {
    28                 return -1;
    29             }
    30 
    31             if (this.BallColor == other.BallColor)
    32             {
    33                 return 0;
    34             }
    35 
    36             if (this.BallColor == EBallColor.Red)
    37             {
    38                 return 1;
    39             }
    40 
    41             return -1;
    42         }
    43     }

    当然用排序的方式是可以的:

    插入排序实现
     1         private static void BallArrange(Ball[] ballList)
     2         {
     3             if (ballList == null || ballList.Length < 2)
     4             {
     5                 return;
     6             }
     7 
     8             for (int i = 0; i < ballList.Length; i++)
     9             {
    10                 int p = i;
    11 
    12                 for (int j = i + 1; j < ballList.Length; j++)
    13                 {
    14                     if (ballList[p].CompareTo(ballList[j]) < 0)
    15                     {
    16                         p = j;
    17                     }
    18                 }
    19 
    20                 if (p != i)
    21                 {
    22                     var tmp = ballList[p];
    23                     ballList[p] = ballList[i];
    24                     ballList[i] = tmp;
    25                 }
    26             }
    27         }

    写的时候就想到排序是很浪费的,各个球没有大小,只有两个值,然后就想到直接把白球放到最后就可以了。于是又写了一种算法。(名字很猥琐)

    抽插实现
     1         static void BallArrange2(IList<Ball> ballList)
     2         {
     3             if (ballList == null || ballList.Count < 2)
     4             {
     5                 return;
     6             }
     7 
     8             int arranged = 0, index = 0;
     9 
    10             while (index < ballList.Count - arranged)
    11             {
    12                 var ball = ballList[index];
    13                 if (ball.BallColor == EBallColor.White)
    14                 {
    15                     ballList.Remove(ball);
    16                     ballList.Add(ball);
    17                     arranged--;
    18                 }
    19                 else
    20                 {
    21                     index++;
    22                 }
    23             }
    24         }

    要是就这么简单,我觉得面试官不会拿来考我。所以应该有优化的算法。在人家明确提出用一次循环搞定问题之后。我想出了下面的算法。

    左右交换实现
     1          static void BallArrange3(Ball[] ballList)
     2          {
     3              if (ballList == null || ballList.Length < 2)
     4              {
     5                  return;
     6              }
     7  
     8              int left = 0, right = ballList.Length - 1;
     9  
    10              while (left < right)
    11              {
    12                  if (ballList[left].BallColor == EBallColor.Red)
    13                  {
    14                      if (ballList[right].BallColor == EBallColor.Red)
    15                      {
    16                          left++;
    17                      }
    18                      else
    19                      {
    20                          left++;
    21                          right--;
    22                      }
    23                  }
    24                  else
    25                  {
    26                      if (ballList[right].BallColor == EBallColor.White)
    27                      {
    28                          right--;
    29                      }
    30                      else
    31                      {
    32                          var tmp = ballList[left];
    33                          ballList[left] = ballList[right];
    34                          ballList[right] = tmp;
    35                          left++;
    36                          right--;
    37                      }
    38                  }
    39              }
    40          }

    写出来就觉得是对了,果然面试官说想要的就是这种“交换”的思路。
    这个算法的思路是:从左开始,发现是红球的,说明符合条件,抛弃之不再管(left++);从右开始,发现是白球的,符合条件,抛弃之不再管(right--),只有左白右红时,交换,然后抛弃之不再管。直到left >= right时,左右都符合条件,结束。

    最后面试官又问了一下Main函数里的测试代码的问题,说能不能只写一个BallArrange函数就实现多种排序算法的测试?我听明白了他想问什么,但是脑子一时堵塞,没有想起那个名词来,于是pardon了一下,然后就明白了,说可以对每个算法分别设置一个类,使其继承一个基类,BallArrange方法继承自基类的虚方法。后来回想起来,这个好像是策略模式吧。然后面试官就说没问题了,想问的就是这个了。

    测试用例
     1         static void Main(string[] args)
     2         {
     3             Ball[] ballList = new Ball[]
     4             {
     5                 new Ball(EBallColor.Red),
     6                 new Ball(EBallColor.White),
     7                 new Ball(EBallColor.White),
     8                 new Ball(EBallColor.Red),
     9                 new Ball(EBallColor.Red),
    10             };
    11 
    12             Console.WriteLine("Before arrange: ");
    13             foreach (var item in ballList)
    14             {
    15                 Console.WriteLine(item);
    16             }
    17 
    18             //BallArrange(ballList);
    19             //BallArrange2(ballList);
    20             BallArrange3(ballList);
    21 
    22             Console.WriteLine("After arrange: ");
    23             foreach (var item in ballList)
    24             {
    25                 Console.WriteLine(item);
    26             }
    27         }
  • 相关阅读:
    课程总结
    课程总结
    十四周实验报告&&课程总结
    记事本代码
    第十三周课程总结
    第十二周课程报告
    PTA实验 链表拼接 (20point(s))
    课程总结
    第十四周课程总结&实验报告
    第十三周课程总结
  • 原文地址:https://www.cnblogs.com/bitzhuwei/p/Red_White_Ball_Arrangement.html
Copyright © 2011-2022 走看看