Bubble Sort冒泡排序
冒泡排序是一种简单的排序算法. 它每次重复的访问过要排序的数列, 一次比较两个元素, 如果他们的顺错误, 就把他们交换过来.
下面这种图很清晰的解释了什么是冒泡算法.
具体算法描述如下:
1. 比较相邻的元素. 如果第一个比第二个大, 就交换他们两个.
2. 对每一对相邻元素作同样的工作, 从开始第一队到结尾的最后一对, 这样在最后的元素应该会是最大的数.
3. 针对所有的元素重复以上的步骤, 除了最后一个.
4. 重复步骤1-3, 直到排序完成.
我们来实现以下bubble sort
// int[] intList = new int[] { 2, -2, 6, 4, 5, 3, 7, 8, 11, 14 }; private void BubbleSort1(int[] intList) { var watch = new Stopwatch(); watch.Start(); var count = 0; for (int i = 0; i < intList.Length; i++) { for (int j = 0; j < intList.Length - 1 - i; j++) { if (intList[j] > intList[j + 1]) // 相邻元素两两对比 { var temp = intList[j + 1]; // 元素交换 intList[j + 1] = intList[j]; intList[j] = temp; } count++; // 计算次数 } } watch.Stop(); var printOut = string.Empty; foreach (var item in intList) { printOut += " " + item; } Console.WriteLine($"Result 1: {printOut}"); Console.WriteLine($"Count time: {count}"); Console.WriteLine($"Response time {watch.Elapsed.TotalMilliseconds.ToString()}ms"); }
以上是最简单的算法.
让我们对bubble sort做个改动已达成最优.
这里我们整理一下思路.
当数组有些数字已经排序好 (e.g. 4,5,6,7), 我们遍历比较一次就没有必要再去比较.
因此, 在排序过程中, 我们可能会重复的去多次比较已经排好的序列, 这样就造成了冗余, 当数据量大时, 会明显的耗时.
为解决这个问题, 我们在这里加一个lastIndex索引, 用于标记最后一次交换的位置.
rivate void BubbleSort2(int[] intList) { var watch = new Stopwatch(); watch.Start(); int i = intList.Length - 1; int count = 0; // 计数 while (i > 1) { int lastChange = 1; // 记录最后一次交换位置 for (int j = 0; j < i; j++) { // 前面比后面大,则进行交换 if (intList[j] > intList[j + 1]) { intList[j] = intList[j] + intList[j + 1]; intList[j + 1] = intList[j] - intList[j + 1]; intList[j] = intList[j] - intList[j + 1]; lastChange = j; // 每交换一次更新一次 } count++; } i = lastChange; } watch.Stop(); var printOut = string.Empty; foreach (var item in intList) { printOut += " " + item; } Console.WriteLine($"Result 1: {printOut}"); Console.WriteLine($"Count time: {count}"); Console.WriteLine($"Response time {watch.Elapsed.TotalMilliseconds.ToString()}ms"); }