using System;
using System.Collections.Generic;
using System.Text;
namespace Chapter35
{
class BubbleSort
{
}
}
using System.Collections.Generic;
using System.Text;
namespace Chapter35
{
class BubbleSort
{
}
}
从这段代码中我们可以知道:
·我们的类在Chapter35命名空间内,由于主程序也在这个命名空间内,不需要 using Chapter35 就可以直接使用 BubbleSort 类。
·系统已经 using 了三个命名空间,可以直接使用这些命名空间里面的类型。
在详细介绍类以及类的各种成员以前,我想先让大家看完整的 BubbleSort.cs代码,这是一典型的类,你可能会惊讶和先前的排序代码相比面目全非。
using System;
using System.Collections.Generic;
using System.Text;
namespace Chapter3
{
enum SortType
{
ASC, //正序 A-Z
DESC //到序 Z-A
}
class BubbleSort
{
# region 字段
// 表示排序类型的私有字段
private SortType order;
// 表示排序数组的私有字段
private int[] list;
// 表示迭代次数的私有字段
private int iterateCount;
# endregion
# region 属性
// 表示排序类型的属性,可读可写
public SortType Order
{
get { return order; }
set { order = value; }
}
// 表示排序数组的属性,可读可写
public int[] List
{
get { return list; }
set { list = value; }
}
// 表示迭代次数的属性,只读
public int IterateCount
{
get { return iterateCount; }
}
# endregion
# region 构造方法
// 没有任何参数的构造方法
public BubbleSort()
{
order = SortType.ASC;
}
// 带有一个参数的重载构造方法
public BubbleSort(int[] arr)
{
list = arr;
order = SortType.ASC;
}
// 带有两个参数的重载构造方法
public BubbleSort(int[] arr, SortType type)
{
list = arr;
order = type;
}
# endregion
# region 私有方法
// 用于交换两个变量私有方法
private void Swap(ref int a, ref int b)
{
int c = a;
a = b;
b = c;
}
# endregion
# region 公有方法
// 用于排序操作的公有方法
public void Sort()
{
bool isOK = false;
iterateCount = 0;
while (!isOK)
{
isOK = true;
for (int i = 0; i < list.Length - 1; i++)
{
iterateCount++;
switch (order)
{
case SortType.ASC:
{
if (list[i] > list[i + 1])
{
Swap(ref list[i], ref list[i + 1]);
isOK = false;
}
break;
}
case SortType.DESC:
{
if (list[i] < list[i + 1])
{
Swap(ref list[i], ref list[i + 1]);
isOK = false;
}
break;
}
}
}
}
}
// 用于把字符数组转化为字符串的公有方法
public string GetDataString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.Length; i++)
sb.Append(list[i]);
return sb.ToString();
}
// 用于把字符数组转化为字符串的公有重载方法,接受一个字符串参数作为分割符
public string GetDataString(string separator)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.Length; i++)
{
sb.Append(list[i]);
sb.Append(separator);
}
sb.Remove(sb.Length - separator.Length, separator.Length);
return sb.ToString();
}
# endregion
}
}
using System.Collections.Generic;
using System.Text;
namespace Chapter3
{
enum SortType
{
ASC, //正序 A-Z
DESC //到序 Z-A
}
class BubbleSort
{
# region 字段
// 表示排序类型的私有字段
private SortType order;
// 表示排序数组的私有字段
private int[] list;
// 表示迭代次数的私有字段
private int iterateCount;
# endregion
# region 属性
// 表示排序类型的属性,可读可写
public SortType Order
{
get { return order; }
set { order = value; }
}
// 表示排序数组的属性,可读可写
public int[] List
{
get { return list; }
set { list = value; }
}
// 表示迭代次数的属性,只读
public int IterateCount
{
get { return iterateCount; }
}
# endregion
# region 构造方法
// 没有任何参数的构造方法
public BubbleSort()
{
order = SortType.ASC;
}
// 带有一个参数的重载构造方法
public BubbleSort(int[] arr)
{
list = arr;
order = SortType.ASC;
}
// 带有两个参数的重载构造方法
public BubbleSort(int[] arr, SortType type)
{
list = arr;
order = type;
}
# endregion
# region 私有方法
// 用于交换两个变量私有方法
private void Swap(ref int a, ref int b)
{
int c = a;
a = b;
b = c;
}
# endregion
# region 公有方法
// 用于排序操作的公有方法
public void Sort()
{
bool isOK = false;
iterateCount = 0;
while (!isOK)
{
isOK = true;
for (int i = 0; i < list.Length - 1; i++)
{
iterateCount++;
switch (order)
{
case SortType.ASC:
{
if (list[i] > list[i + 1])
{
Swap(ref list[i], ref list[i + 1]);
isOK = false;
}
break;
}
case SortType.DESC:
{
if (list[i] < list[i + 1])
{
Swap(ref list[i], ref list[i + 1]);
isOK = false;
}
break;
}
}
}
}
}
// 用于把字符数组转化为字符串的公有方法
public string GetDataString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.Length; i++)
sb.Append(list[i]);
return sb.ToString();
}
// 用于把字符数组转化为字符串的公有重载方法,接受一个字符串参数作为分割符
public string GetDataString(string separator)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.Length; i++)
{
sb.Append(list[i]);
sb.Append(separator);
}
sb.Remove(sb.Length - separator.Length, separator.Length);
return sb.ToString();
}
# endregion
}
}
调用类的代码如下:
int[] list1 = { 1, 0, 6, 5, 7, 9, 2, 8, 3, 4 };
BubbleSort sort = new BubbleSort(list1);
Console.WriteLine("排序前: " + sort.GetDataString());
sort.Sort();
Console.WriteLine("迭代次数: " + sort.IterateCount);
Console.WriteLine("排序后: " + sort.GetDataString());
Console.WriteLine("---------------------分割符---------------------");
int[] list2 = { 7, 6, 9, 8, 5, 3, 4, 2, 1, 0 };
sort.List = list2;
Console.WriteLine("排序前: " + sort.GetDataString());
sort.Order = SortType.DESC;
sort.Sort();
Console.WriteLine("迭代次数: " + sort.IterateCount);
Console.WriteLine("排序后: " + sort.GetDataString("->"));
BubbleSort sort = new BubbleSort(list1);
Console.WriteLine("排序前: " + sort.GetDataString());
sort.Sort();
Console.WriteLine("迭代次数: " + sort.IterateCount);
Console.WriteLine("排序后: " + sort.GetDataString());
Console.WriteLine("---------------------分割符---------------------");
int[] list2 = { 7, 6, 9, 8, 5, 3, 4, 2, 1, 0 };
sort.List = list2;
Console.WriteLine("排序前: " + sort.GetDataString());
sort.Order = SortType.DESC;
sort.Sort();
Console.WriteLine("迭代次数: " + sort.IterateCount);
Console.WriteLine("排序后: " + sort.GetDataString("->"));
不去看代码,从运行后的效果可以看出这个 BubbleSort 类相比先前做的例子有以下改进:
·支持从小到大、从大到小两种排序类型。
·支持自定义输出的分割符,比如“->”。
·可以知道排序的迭代次数。
假设冒泡排序类是别人写的,我们先来看一下调用的代码熟悉.NET下对象使用:
1. 第一行代码声明了一个整数数组用于排序。
2. 第二行代码实例化了一个 BubbleSort 类。前面提到过,类是一个抽象的东西,要为我们所用就需要先得到一个实例。就好比我们先要买一个真正的房子然后才能居住。BubbleSort sort = new BubbleSort(list1); 在实例化的时候把排序数组直接赋值给类的构造方法,然后得到的实例为 sort。构造方法可以理解为一个初始化方法。
3. 第三行代码调用了 BubbleSort 的 GetDataString()方法。GetDataString()方法返回一个字符串表示数组的内容。方法可以理解为一个具有某种操作的功能,可以接受一些参数并返回一个值,在这里的GetDataString()方法返回一个字符串。
4. 第4行代码调用了 BubbleSort 的 Sort() 方法进行排序操作。 Sort()方法不返回任何值。
5. 第5行代码输出 BubbleSort 的 IterateCount 属性的值,它表示某次排序操作的迭代(循环)次数。
6. 第6行代码再次调用 BubbleSort 的 GetDataString() 方法输出排序后的数组。
7. 第7行代码输出了一行分割符,用于再一次的反向排序。
8. 第8行代码声明了另外一个整数数组用于排序。
9. 第9行代码重新设置了 BubbleSort 的 List 属性为新的数组
10. 第10行代码调用了 BubbleSort 的 GetDataString()方法输出排序前的数组。
11. 第11行代码设置 BubbleSort 的 Order 属性为 SortType.DESC,表示排序方式使用倒序。Order性中的类型是SortType枚举。鼠标停留在Order字段上,IDE显示了属性的类型。
12. 第12行代码再次调用 BubbleSort 的 Sort() 方法进行排序操作。
13. 第13行代码输出迭代次数。
14. 第14行代码再次调用了BubbleSort的GetDataString()方法输出拓序后的数组。和上次排序不同,这里我们为GetDataString()赋值了一个分割符,数组的每个元素都使用“->”进行分割。你可能会奇怪,我们调用的都是GetDataString()方法,怎么一次可以使用参数一次又不可以使用参数?这个问题暂留着稍后回答。
BubbleSort 类的确工作得很好,我们并不需要知道它是怎么实现这些功能的,我们只需要知道怎么使用就可以了。这些程序设计模式和现实世界很像。一个庞大的程序就好似现实世界,就以Windows操作系统为例,这么一个庞大的操作系统不可能是由一个程序员完成的,而是由数百个程序员共同设计而成。程序员们各自实现自己的那个模块,根本不需要考虑其它程序员的代码是如何编写的。