在阅读此博文前,请先阅读我的博文“C#排序算法——基类设计 “,以了解基类的结构。
假设有一个IList<T>型的集合list(集合的元素为list[0]到list[n-1], n = list.Count)那么选择法的排序过程如下:
第1次遍历,从list[0]开始,到list[n-1]结束,找出list[0]到list[n-1]中最大的元素(降序则为最小的元素),设为max,将max与list[n-1]互换,显然索引号n-1位置的元素已经排好了。
第2次遍历,从list[0]开始,到list[n-2]结束,找出list[0]到list[n-2]中最大的元素(降序则为最小的元素),设为max,将max与list[n-2]互换,显然索引号n-2位置的元素也排好了。
...
第i次遍历,从list[0]开始,到list[n-i]结束,找出list[0]到list[n-i]中最大的元素(降序则为最小的元素),设为max,将max与list[n-i]互换,显然索引号n-i位置的元素也排好了。
...
第n-1次遍历,从list[0]开始,到list[1]结束,找出list[0]到list[1]中最大的元素(降序则为最小的元素),设为max,将max与list[1]互换,显然索引号0,1位置的元素都排好了。
同冒泡法一样,经过n-1次排列后,所有元素的位置都确定了。好了,现在将上面的文字描述转变成代码:
- public class SelectionSorter : Sorter
- {
- public override void Sort<T>(IList<T> list, CompareDelegate<T> compare)
- {
- for ( int endIndex = list.Count - 1; endIndex > 0; endIndex--) //endIndex,子集结束位置的索引
- {
- int maxIndex = 0; //子集中最大值元素的索引号
- for ( int index = 0; index <= endIndex; index++) //找到list[0]到list[endIndex]中最大的元素,将其索引号赋值给maxIndex
- {
- if (compare(list[maxIndex], list[index]) < 0)
- {
- maxIndex = index;
- }
- }
- if (maxIndex != endIndex)
- {
- SwapListItem(list, maxIndex, endIndex); //如果list[endIndex]不是最大的元素,将list[endIndex]与list[maxIndex]互换
- }
- }
- }
上面的代码仍然不太完善,仍然存在效率问题,假设list已经排序过,我们的代码应该最多进行一次扫描(判断list是否需要排序),而不是傻傻地进行n-1次扫描。好了,现在得到我们的最终代码:
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace CYB.DataStruct.Sorting
- {
- /// <summary>
- /// 作者 : cyb
- /// 发表时间 : 2008-9-8
- /// qq : 13101908
- /// e-mail : hustcyb@gmail.com
- /// </summary>
- public class SelectionSorter : Sorter
- {
- public override void Sort<T>(IList<T> list, CompareDelegate<T> compare)
- {
- base .Sort(list, compare);
- bool sorted = false ; //判断list是否已经排序好的布尔变量
- for ( int endIndex = list.Count - 1; endIndex > 0 && !sorted; endIndex--)
- {
- int maxIndex = 0;
- sorted = true ; //先假定已经排好序
- for ( int index = 1; index <= endIndex; index++)
- {
- if (compare(list[maxIndex], list[index]) < 0)
- {
- maxIndex = index;
- }
- else
- {
- sorted = false ; //这里要注意,当且仅当list[0] < list[1] < .. <list[endIndex]时,sorted为true
- }
- }
- if (maxIndex != endIndex)
- {
- SwapListItem(list, endIndex, maxIndex);
- }
- }
- }
- }
- }