一、冒泡排序原理
1、把两个相邻的元素两两比较,当一个元素大于右侧相邻的元素时,则交换他们的位置,最后的元素一定是最大的数;
2、当一个元素小于或等于右侧的相邻元素时,位置不变。
3、所有的元素都要重复以上的1、2两个步骤。
二、冒泡排序的时间复杂度
平均的时间复杂度为【】
三、冒泡排序的稳定性
泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
四、冒泡排序核心
/***
* Title: "算法" 项目
* 主题 : 冒泡排序
* Description:
* 功能 :
* Date: 2020-06-19
* Version: 1.2
* Author: Coffee
* Modify Recoder:
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Kernal
{
class BubbleSort
{
//冒泡排序(基础版本)
public static int[] BaseSort(int[] array, SortType sortType=SortType.ASC)
{
if (array != null && array.Length > 0)
{
int len = array.Length;
int tmp = 0;
switch (sortType)
{
case SortType.ASC:
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j < len-i-1; j++)
{
if (array[j] > array[j + 1])
{
tmp = array[j + 1];
array[j + 1] = array[j];
array[j] = tmp;
}
}
}
break;
case SortType.DESC:
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j < len-i-1; j++)
{
if (array[j] < array[j + 1])
{
tmp = array[j+1];
array[j + 1] = array[j];
array[j] = tmp;
}
}
}
break;
default:
break;
}
}
return array;
}
//冒泡排序(升级版)
public static int[] UpgradeSort(int[] array, SortType sortType = SortType.ASC)
{
if (array != null && array.Length > 0)
{
int len = array.Length;
int tmp = 0;
//有序标记
bool isSorted = true;
//记录最后一次交互的位置
int lastExchangeInde = 0;
//无序边界每次比较都只需比较到这里
int sortBorder = len - 1;
switch (sortType)
{
case SortType.ASC:
for (int i = 0; i < len - 1; i++)
{
isSorted = true;
for (int j = 0; j < sortBorder; j++)
{
if (array[j] > array[j + 1])
{
tmp = array[j + 1];
array[j + 1] = array[j];
array[j] = tmp;
//因为有元素交换,所以不是有序
isSorted = false;
//更新为最后一次交换的元素位置
lastExchangeInde = j;
}
}
sortBorder = lastExchangeInde;
if (isSorted)
{
break;
}
}
break;
case SortType.DESC:
for (int i = 0; i < len - 1; i++)
{
isSorted = true;
for (int j = 0; j < sortBorder; j++)
{
if (array[j] < array[j + 1])
{
tmp = array[j + 1];
array[j + 1] = array[j];
array[j] = tmp;
//因为有元素交换,所以不是有序
isSorted = false;
//更新为最后一次交换的元素位置
lastExchangeInde = j;
}
}
sortBorder = lastExchangeInde;
if (isSorted)
{
break;
}
}
break;
default:
break;
}
}
return array;
}
//冒泡排序(鸡尾酒版)【大多数元素已经有序的情况使用】
public static int[] CocktailSort(int[] array, SortType sortType = SortType.ASC)
{
if (array != null && array.Length > 0)
{
int len = array.Length;
//缓存内容
int tmp = 0;
//有序标记
bool isSorted = true;
switch (sortType)
{
case SortType.ASC:
for (int i = 0; i < len/2; i++)
{
//每轮初始值都是true
isSorted = true;
for (int j = 0; j < len - i - 1; j++)
{
if (array[j] > array[j + 1])
{
tmp = array[j + 1];
array[j + 1] = array[j];
array[j] = tmp;
//因为有元素交换,所以不是有序则为false
isSorted = false;
}
}
if (isSorted)
{
break;
}
//在偶数轮之前,将isSorted重置为true
isSorted = true;
//偶数轮,从右向左比较和交换
for (int j = len - i - 1; j >i; j--)
{
if (array[j]<array[j-1])
{
tmp = array[j];
array[j] = array[j-1];
array[j - 1] = tmp;
//因为有元素交换,所以不是有序则为false
isSorted = false;
}
}
if (isSorted)
{
break;
}
}
break;
case SortType.DESC:
for (int i = 0; i < len/2; i++)
{
//每轮初始值都是true
isSorted = true;
for (int j = 0; j < len - i - 1; j++)
{
if (array[j] < array[j + 1])
{
tmp = array[j + 1];
array[j + 1] = array[j];
array[j] = tmp;
//因为有元素交换,所以不是有序则为false
isSorted = false;
}
}
if (isSorted)
{
break;
}
//在偶数轮之前,将isSorted重置为true
isSorted = true;
//偶数轮,从右向左比较和交换
for (int j = len - i - 1; j > i; j--)
{
if (array[j] > array[j - 1])
{
tmp = array[j];
array[j] = array[j - 1];
array[j - 1] = tmp;
//因为有元素交换,所以不是有序则为false
isSorted = false;
}
}
if (isSorted)
{
break;
}
}
break;
default:
break;
}
}
return array;
}
}//Class_end
//排序类型
public enum SortType
{
ASC, //升序
DESC, //降序
}
}
五、使用方法
①、引用命名空间:using Kernal;
②、BubbleSort+方法名称;
③、在方法中传入列表即可。
六、示例
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Kernal;
namespace CommonSort
{
class Program
{
static void Main(string[] args)
{
//时间计时器
Stopwatch _SW = new Stopwatch();
Console.WriteLine("原数组为:");
int[] array = { 69,25,78,1,56,24,98,71,2,6,1,5,8,9};
int[] array2 = { 69, 25, 78, 1, 56, 24, 98, 71, 2, 6, 1, 5, 8, 9 };
int[] array3 = { 69, 25, 78, 1, 56, 24, 98, 71, 2, 6, 1, 5, 8, 9 };
Display(array);
Console.WriteLine("---------------基础冒泡排序----------------------");
_SW.Start();
Console.WriteLine("【升序】基础冒泡排序后的数组为:");
int[] tmp = BubbleSort.BaseSort(array);
Display(tmp);
_SW.Stop();
Console.WriteLine("花费时间为:{0} 毫秒",_SW.Elapsed.TotalMilliseconds);
_SW.Restart();
Console.WriteLine("【降序】基础冒泡排序后的数组为:");
int[] tmp2 = BubbleSort.BaseSort(array,SortType.DESC);
Display(tmp2);
_SW.Stop();
Console.WriteLine("花费时间为:{0} 毫秒\n", _SW.Elapsed.TotalMilliseconds);
Console.WriteLine("---------------升级版冒泡排序----------------------");
_SW.Restart();
Console.WriteLine("【升序】升级版冒泡排序后的数组为:");
int[] tmp3 = BubbleSort.UpgradeSort(array2);
Display(tmp3);
_SW.Stop();
Console.WriteLine("花费时间为:{0} 毫秒", _SW.Elapsed.TotalMilliseconds);
_SW.Restart();
Console.WriteLine("【降序】升级版冒泡排序后的数组为:");
int[] tmp4 = BubbleSort.UpgradeSort(array2, SortType.DESC);
Display(tmp4);
_SW.Stop();
Console.WriteLine("花费时间为:{0} 毫秒\n", _SW.Elapsed.TotalMilliseconds);
Console.WriteLine("---------------鸡尾酒版冒泡排序----------------------");
_SW.Restart();
Console.WriteLine("【升序】鸡尾酒版冒泡排序后的数组为:");
int[] tmp5 = BubbleSort.CocktailSort(array3);
Display(tmp5);
_SW.Stop();
Console.WriteLine("花费时间为:{0} 毫秒", _SW.Elapsed.TotalMilliseconds);
_SW.Restart();
Console.WriteLine("【降序】鸡尾酒版冒泡排序后的数组为:");
int[] tmp6 = BubbleSort.CocktailSort(array3,SortType.DESC);
Display(tmp6);
_SW.Stop();
Console.WriteLine("花费时间为:{0} 毫秒", _SW.Elapsed.TotalMilliseconds);
Console.Read();
}//Main_end
//显示结果
private static void Display(int[] array)
{
string str = null;
foreach (var item in array)
{
str += item + " ";
}
Console.WriteLine(str);
}
}//Class_end
}
七、结果如下:
’