该算法来源于[数据结构(C语言版)].严蔚敏_吴伟民.,这里根据自己需要换成了c#语言,有的不清楚,是在百度百科搜索后整理了一下,记录下来的,
数组从[0..n-1]进行排序的
测试数据:int[] array = { 49, 38, 65, 97, 76, 13, 27, 49 };
1.直接插入排序
/// <summary> /// 对数组array[0..n-1]进行直接插入排序 /// 基本操作:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序 /// 直接插入排序属于稳定的排序 /// 时间复杂性为O(n^2),空间复杂度为O(1) /// </summary> public void InsertSort(int[] array) { int i, j, temp; for ( i = 1; i < array.Length; i++) //第二个记录开始比较 { temp = array[i]; //temp 暂存array[i] for (j = i; j > 0 && temp < array[j - 1]; --j)// array[i]<array[i-1],需要将array[i]插入到有序列中 { array[j] = array[j - 1]; //记录后移 } array[j] = temp; //插入正确位置 } }
2.折半插入排序
/// <summary> /// 折半插入排序算法是一种稳定的排序算法,比直接插入算法明显减少了关键字之间比较的次数,速度比直接插入排序算法快,但记录移动的次数没有变/// 时间复杂度为O(n^2),附加空间O(1) /// 具体操作: /// 在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high], /// 则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较, /// 如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1), /// 否则选择a[m+1]到a[high]为新的插入区域(即low=m+1), /// 如此直至low<=high不成立,[2]即将此位置之后所有元素后移一位,并将新元素插入a[high+1] /// </summary> public void BinaryInsertSort(int[] array) { for (int i = 1; i < array.Length; i++) { int temp = array[i]; int low = 0; int high = i - 1; while (low <= high) { int mid = (low + high) / 2; if (temp < array[mid]) //比参考元素小,则选择a[low]到a[mid-1]为新的插入区域(即high=mid-1) { high = mid - 1; } else { low = mid + 1; } }for (int j = i; j >= low + 1; j--) { array[j] = array[j - 1];//记录后移 }array[low] = temp;//插入位置 } }
3.希尔排序
/// <summary> /// 希尔排序(插入排序) /// 希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序 /// 基本思想 /// 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。 /// 先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组
/// 中进行直接插入排序为止。
/// 希尔排序是不稳定的 /// </summary> /// <param name="array"></param> /// <param name="dk"></param> public void ShellInsert(int[] array, int dk) { int i, j, r0;
for (i = dk; i < array.Length; ++i) { if (array[i] < array[i - dk]) //需将array[i]插入有序增量子表 { r0 = array[i]; //暂存
for (j = i - dk; j >= 0 && r0 < array[j]; j -= dk) //j>=0 以防下标越界 array[j + dk] = array[j]; //记录后移,查找插入位置
array[j + dk] = r0; //插入array[i]到正确位置 } } }
2种增量的取值:
/// <summary> /// 按增量序列dlta[0..t-1]对顺序表array作希尔排序 /// 增量序列如:1,2,3,5,9,... /// 算法:dlta[k]= 2的(t-k)次方 + 1, 0<=k<=t<=log2(n-1)取最小值
///int[] dlta = { 1,2,3,5,9}; /// </summary> public void ShellSort(int[] array, int[] dlta) { for (int k = dlta.Length - 1; k >= 0; k--) ShellInsert(array, dlta[k]);//一趟增量为dlta[k]的插入排序 }
/// <summary> /// 按增量序列 n=n/3+1 对顺序表array作希尔排序 /// </summary>
public void ShellSort(int[] array) { int n = array.Length;//增量初值,这里测试取的数组的长度 do { n = n / 3 + 1; //求下一增量 ShellInsert(array, n);//一趟增量为n的shell插入排序 } while (n > 1); }