1. 冒泡排序原理
-
假设有一排数组,从第一个开始,将其与后面一个数进行比较,如果后面的数比这个数小,就交换这两个数的位置。
-
这样第二个数就一定比第一个数大了。接着再继续将第二个数和第三个数进行比较,同样的进行交换,如此反复到n次。
-
比较n次之后,可以知道,第n个位置的数一定是最大的。继续重复上面1,2的步骤,这一次就不用将第n-1和第n个比较了,因为第n个在上一步中已知是最大的了。由此可以推出冒泡排序的复杂度是(1+2+3+……+n) 用大O 表示法就是O(n2)
2. 冒泡排序优化
在比较的过程中,假设一个数组是21345678,此时的外层循环还只进行了3次,按照道理还需要进行4次,从数据中可以发现,只需要再进行1次将2和1的位置对调即可,剩下的3次就完全是多余的比较操作。
可以在外层循环中添加一个bool的标志位,当发现有一次的内层循环只进行了比较而没有交换,就跳出外层循环。代码如下
//冒泡排序算法
public static void buddle(int[] arrays)
{
//冒泡优化
for (int i = 0; i < arrays.Length; i++)
{
bool isChange = false;
for (int j = 0; j < arrays.Length - i - 1; j++)
{
if (arrays[j] > arrays[j + 1])
{
int temp;
temp = arrays[j];
arrays[j] = arrays[j + 1];
arrays[j + 1] = temp;
isChange = true;
}
}
if (!isChange)
{
break;
}
}
}
3.泛型+委托扩展冒泡排序
上面的冒泡排序只能排序数字,不能比较任意类型.想要比较任意类型的对象,需要泛型+委托来扩展冒泡排序的算法。
改进泛型+委托算法:
public static void CommonBuddle<T>(T[] dataArrays, Func<T, T, bool> compareFuc)
{
//冒泡优化
for (int i = 0; i < dataArrays.Length; i++)
{
bool isChange = false;
for (int j = 0; j < dataArrays.Length - i - 1; j++)
{
if (compareFuc(dataArrays[j], dataArrays[j + 1]))
{
T temp;
temp = dataArrays[j];
dataArrays[j] = dataArrays[j + 1];
dataArrays[j + 1] = temp;
isChange = true;
}
}
if (!isChange)
{
break;
}
}
}
员工类:
public class Employ
{
public string Name { get; private set; }
public int Salary { get; private set; }
public Employ(string name, int salary)
{
this.Name = name;
this.Salary = salary;
}
public static bool compareFuc(Employ a, Employ b)
{
//比较两个员工的工资大小
if (a.Salary > b.Salary) return true;
return false;
}
public override string ToString()
{
return Name + ":" + Salary;
}
}
测试:
public static Employ[] employs = new Employ[]
{
new Employ("lei",12),
new Employ("ledi",34),
new Employ("lefi",564),
new Employ("leig",23),
new Employ("leri",4),
new Employ("lhei",9),
new Employ("lhei",45),
};
public static void Main(string[] args)
{
buddle(arrays);
for (int i = 0; i < arrays.Length; i++)
{
Console.WriteLine(arrays[i]);
}
CommonBuddle<Employ>(employs, Employ.compareFuc);
foreach(var emply in employs)
{
Console.WriteLine(emply);
}
Console.ReadKey();
}