C# 经典排序算法大全

选择排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace sorter
{
public class SelectionSorter
{
private int min;
public void Sort(int[] arr)
{
for (int i = 0; i < arr.Length - 1; ++i)
{
min = i;
for (int j = i + 1; j < arr.Length; ++j)
{
if (arr[j] < arr[min])
{
min = j;
}
}
int t = arr[min];
arr[min] = arr[i];
arr[i] = t;
}
}
} class Program
{
static void Main(string[] args)
{
int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
SelectionSorter selSor = new SelectionSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}

冒泡排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace sorter
{
public class EbullitionSorter
{
public void Sort(int[] arr)
{
int i, j, temp;
bool done = false;
j = 1;
while ((j < arr.Length) && (!done)) // 推断长度
{
done = true;
for (i = 0; i < arr.Length - j; i++)
{
if (arr[i] > arr[i + 1])
{
done = false;
temp = arr[i];
arr[i] = arr[i + 1]; // 交换数据
arr[i + 1] = temp;
}
}
j++;
}
}
} class Program
{
static void Main(string[] args)
{
int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
EbullitionSorter selSor = new EbullitionSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}

高速排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace sorter
{
public class QuickSorter
{
private void swap(ref int l, ref int r)
{
int temp;
temp = l;
l = r;
r = temp;
} public void Sort(int[] list, int low, int high)
{
int pivot; // 存储分支点
int l, r;
int mid;
if (high <= low)
{
return;
}
else if (high == low + 1)
{
if (list[low] > list[high])
{
swap(ref list[low], ref list[high]);
}
return;
}
mid = (low + high) >> 1;
pivot = list[mid];
swap(ref list[low], ref list[mid]);
l = low + 1;
r = high;
do
{
while (l <= r && list[l] < pivot)
{
l++;
}
while (list[r] >= pivot)
{
r--;
}
if (l < r)
{
swap(ref list[l], ref list[r]);
}
} while (l < r);
list[low] = list[r];
list[r] = pivot;
if (low + 1 < r)
{
Sort(list, low, r - 1);
}
if (r + 1 < high)
{
Sort(list, r + 1, high);
}
}
} class Program
{
static void Main(string[] args)
{
int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
QuickSorter selSor = new QuickSorter();
selSor.Sort(arrInt, 0, arrInt.Length - 1);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}

插入排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace sorter
{
public class InsertionSorter
{
public void Sort(int[] arr)
{
for (int i = 1; i < arr.Length; i++)
{
int t = arr[i];
int j = i;
while ((j > 0) && (arr[j - 1] > t))
{
arr[j] = arr[j - 1]; // 交换顺序
--j;
}
arr[j] = t;
}
}
} class Program
{
static void Main(string[] args)
{
int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
InsertionSorter selSor = new InsertionSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}

希尔排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace sorter
{
public class ShellSorter
{
public void Sort(int[] arr)
{
int inc;
for (inc = 1; inc <= arr.Length / 9; inc = 3 * inc + 1) ;
for (; inc > 0; inc /= 3)
{
for (int i = inc + 1; i <= arr.Length; i += inc)
{
int t = arr[i - 1];
int j = i;
while ((j > inc) && (arr[j - inc - 1] > t))
{
arr[j - 1] = arr[j - inc - 1]; // 交换数据
j -= inc;
}
arr[j - 1] = t;
}
}
}
} class Program
{
static void Main(string[] args)
{
int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
ShellSorter selSor = new ShellSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}

归并排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Merge
{
public class Function
{
private int Groups;
private int CopyGroups;
private int mergerows;
private int[] Array27;
private static Random ran = new Random();
public Function(int length)
{
Array27 = new int[length];
for (int i = 0; i < length; i++)
Array27[i] = ran.Next(1, 100);
}
//选择
public void ToMergeSort()
{
MergeSort(Array27);
}
public void ToRecursiveMergeSort()
{
RecursiveMergeSort(Array27, 0, Array27.Length - 1);
}
public void ToNaturalMergeSort()
{
NaturalMergeSort(Array27);
} /// <summary>
/// 归并排序(递归)
/// 核心思想:(分治)
/// 将待排序元素(递归直至元素个数为1)分成左右两个大小大致同样的2个子集合。然后。
/// 分别对2个子集合进行排序,终于将排好序的子集合合并成为所要求的排好序的集合.
/// 核心算法时间复杂度:
/// T(n)=O(nlogn)
/// </summary>
/// <param name="Array"></param>
/// <param name="left"></param>
/// <param name="right"></param>
public void RecursiveMergeSort(int[] Array, int left, int right)
{
int middle = (left + right) / 2; if (left < right)
{
//对前半部分递归拆分
RecursiveMergeSort(Array, left, middle);
//对后半部分递归拆分
RecursiveMergeSort(Array, middle + 1, right);
MergeOne(Array, left, middle, right);
}
}
public void MergeOne(int[] Array, int left, int middle, int right)
{
int leftindex = left;
int rightindex = middle + 1;
//动态暂时二维数组存放切割为两个小Array的数组排列顺序后的数据
int[] merge = new int[right + 1];
int index = 0;
//对两个小数组合并排序
while (leftindex <= middle && rightindex <= right)
merge[index++] = (Array[leftindex] - Array[rightindex]) >= 0 ? Array[rightindex++] : Array[leftindex++];
//有一側子数列遍历完后,将另外一側子数列剩下的数依次放入暂存数组中(有序)
if (leftindex <= middle)
{
for (int i = leftindex; i <= middle; i++)
merge[index++] = Array[i];
}
if (rightindex <= right)
{
for (int i = rightindex; i <= right; i++)
merge[index++] = Array[i];
}
//将有序的数列 写入目标数组 ,即原来把Array数组分为两个小Array数组后又一次有序组合起来(覆盖原数组)
index = 0;
for (int i = left; i <= right; i++)
Array[i] = merge[index++];
} /// <summary>
/// 归并排序(非递归)
/// 核心思想:(分治)
/// 对n个数的数列每相邻两个元素排序。组成n/2个或(n+1)/2个子数组,单个的不比了直接进入下一轮。
/// 然后对每一个相邻的子数组再排序,以此类推最后得到排好序的数列
/// forexample: 59 35 54 28 52
/// 排序And分: 35 59. 28 54. 52
/// 排序And分: 28 35 54 59. 52
/// 结果: 28 35 52 54 59
/// 核心算法时间复杂度:
/// T(n)=O(nlogn)
/// </summary>
/// <param name="Array"></param>
public void MergeSort(int[] Array)
{
//index固定的数组
int[] merge = new int[Array.Length];
int P = 0;
while (true)
{
int index = 0;
//子数组元素的个数
int ENumb = (int)Math.Pow(2, P);
//一个子数组中的元素个数与数组的一半元素个数比較大小
//最糟糕的情况最右边的数组仅仅有一个元素
if (ENumb < Array.Length)
{
while (true)
{
int TorFAndrightindex = index;
//最后一个子数组的第一个元素的index与数组index相比較
if (TorFAndrightindex <= Array.Length - 1)
MergeTwo(Array, merge, index, ENumb);
else
break;
index += 2 * ENumb;
}
}
else
break;
P++;
}
}
public void MergeTwo(int[] Array, int[] merge, int index, int ENumb)
{
//换分两个子数组的index(千万不能用middle = (right + left) / 2划分)
// 1
int left = index;
int middle = left + ENumb - 1;
//(奇数时)
//排除middleindex越界
if (middle >= Array.Length)
{
middle = index;
}
//同步化merge数组的index
int mergeindex = index;
// 2
int right;
int middleTwo = (index + ENumb - 1) + 1;
right = index + ENumb + ENumb - 1;
//排除最后一个子数组的index越界.
if (right >= Array.Length - 1)
{
right = Array.Length - 1;
}
//排序两个子数组并拷贝到merge数组
while (left <= middle && middleTwo <= right)
{
merge[mergeindex++] = Array[left] >= Array[middleTwo] ? Array[middleTwo++] : Array[left++];
}
//两个子数组中当中一个比較完了(Array[middleTwo++] 或Array[left++])。
//把当中一个数组中剩下的元素复制进merge数组。
if (left <= middle)
{
//排除空元素.
while (left <= middle && mergeindex < merge.Length)
merge[mergeindex++] = Array[left++];
}
if (middleTwo <= right)
{
while (middleTwo <= right)
merge[mergeindex++] = Array[middleTwo++];
}
//推断是否合并至最后一个子数组了
if (right + 1 >= Array.Length)
Copy(Array, merge);
} /// <summary>
/// 自然归并排序:
/// 对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段.
/// 比如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段
/// 有{4,8},{3,7},{1,5,6},{2}.
/// 用一次对数组a的线性扫描就足以找出全部这些排好序的子数组段.
/// 然后将相邻的排好序的子数组段两两合并,
/// 构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}).
/// 继续合并相邻排好序的子数组段,直至整个数组已排好序.
/// 核心算法时间复杂度:
/// T(n)=○(n);
/// </summary>
public void NaturalMergeSort(int[] Array)
{
//得到自然划分后的数组的index组(每行为一个自然子数组)
int[,] PointsSymbol = LinearPoints(Array);
//子数组仅仅有一个。
if (PointsSymbol[0, 1] == Array.Length - 1)
return;
//多个(至少两个子数组)...
else
//能够堆栈调用吗?
NaturalMerge(Array, PointsSymbol); }
public void NaturalMerge(int[] Array, int[,] PointsSymbol)
{
int left;
int right;
int leftend;
int rightend; mergerows = GNumberTwo(Groups);
CopyGroups = Groups;
//固定状态
int[] TempArray = new int[Array.Length];
//循环取每一个自然子数组的index
while (true)
{
// int Temprow = 1;
//仅仅记录合并后的子数组(”《应该为》“动态的)
int[,] TempPointsSymbol = new int[mergerows, 2]; int row = 0;
do
{
//最重要的推断:最后(一组子数组)是否可配对
if (row != CopyGroups - 1)
{ //以上条件也能够含有(& 和&&的差别)短路运算
//參考:http://msdn.microsoft.com/zh-cn/library/2a723cdk(VS.80).aspx
left = PointsSymbol[row, 0];
leftend = PointsSymbol[row, 1];
right = PointsSymbol[row + 1, 0];
rightend = PointsSymbol[row + 1, 1];
MergeThree(Array, TempArray, left, leftend, right, rightend);
MergePointSymbol(PointsSymbol, TempPointsSymbol, row);
}
else
{
////默认剩下的单独一个子数组已经虚拟合并。然后Copy进TempArray。
int TempRow = PointsSymbol[row, 0];
int TempCol = PointsSymbol[row, 1];
while (TempRow <= TempCol)
TempArray[TempRow] = Array[TempRow++];
//TempPointSymbol完整同步
TempPointsSymbol[row / 2, 0] = PointsSymbol[row, 0];
TempPointsSymbol[row / 2, 1] = PointsSymbol[row, 1];
break;//又一次開始新一轮循环。
}
row += 2;
// Temprow++;
//合并到仅仅有一个子数组时结束循环
if (TempPointsSymbol[0, 1] == Array.Length - 1)
break;
}//推断别进入越界循环(能够进孤单循环)这里指的是PointsSymbol的子数组个数
while (row <= CopyGroups - 1);
//
Copy(Array, TempArray);
//更新子数组index,row为跳出循环的条件(最后单个子数组或下一个越界的第一个)
UpdatePointSymbol(PointsSymbol, TempPointsSymbol, row);
//改变TempPointsSymbol的行数(合并后子数组数)
mergerows = GNumber(mergerows);
CopyGroups = GNumberTwo(CopyGroups);
//合并到仅仅有一个子数组时结束循环
if (PointsSymbol[0, 1] == Array.Length - 1)
break;
}
//输出
}
public int GNumber(int Value)
{
if (Value % 2 == 0)
Value /= 2;
else
Value -= 1; return Value;
}
public int GNumberTwo(int Value)
{
if (Value % 2 == 0)
mergerows = Value / 2;
else
mergerows = Value / 2 + 1;
return mergerows;
}
public void MergeThree(int[] Array, int[] Temp, int left, int leftend, int right, int rightend)
{
//合并语句
int index = left;
while (left <= leftend && right <= rightend)
Temp[index++] = Array[left] >= Array[right] ? Array[right++] : Array[left++];
while (left <= leftend)
Temp[index++] = Array[left++];
while (right <= rightend)
Temp[index++] = Array[right++];
}
public void MergePointSymbol(int[,] PointsSymbol, int[,] TempPointsSymbol, int row)
{
int rowindex = row / 2;
TempPointsSymbol[rowindex, 0] = PointsSymbol[row, 0];
TempPointsSymbol[rowindex, 1] = PointsSymbol[row + 1, 1];
}
public void UpdatePointSymbol(int[,] PointsSymbol, int[,] TempPointsSymbol, int rows)
{
int row = 0;
//if (mergerows % 2 == 0)
//{
for (; row < TempPointsSymbol.GetLength(0); row++)
{
for (int col = 0; col < 2; col++)
PointsSymbol[row, col] = TempPointsSymbol[row, col];
}
//后面的清零
for (; row < PointsSymbol.GetLength(0); row++)
{
for (int col2 = 0; col2 < 2; col2++)
PointsSymbol[row, col2] = 0;
}
//}
////补剩下的index组,
//else
//{
// for (int row2 = 0; row2 < TempPointsSymbol.GetLength(0); row2++)
// {
// for (int col3 = 0; col3 < 2; col3++)
// PointsSymbol[row2, col3] = TempPointsSymbol[row2, col3];
// }
// //最后一个子数组的index仅仅有一个。 // int row3 = TempPointsSymbol.GetLength(0);
// PointsSymbol[row3, 0] = PointsSymbol[rows, 0];
// PointsSymbol[row3, 1] = PointsSymbol[rows, 1];
// //后面的清零
// for (int row4 = row3 + 1; row4 < PointsSymbol.GetLength(0); row4++)
// {
// for (int col4 = 0; col4 < 2; col4++)
// PointsSymbol[row4, col4] = 0;
// }
//} }
public int[,] LinearPoints(int[] Array)
{
Groups = 1;
int StartPoint = 0;
int row = 0;
int col = 0;
//最糟糕的情况就是有Array.Length行。
int[,] PointsSet = new int[Array.Length, 2];
//线性扫描Array,划分数组
//初始前index=0
PointsSet[row, col] = 0;
do
{
//推断升序子数组终于的index开关
bool Judge = false;
//从Array第二个数推断是否要结束或者是否是升序子数组.
while (++StartPoint < Array.Length && Array[StartPoint] < Array[StartPoint - 1])
{
//打开第一个升序子数组结束的index开关
Judge = true;
//又一次開始第二个升序子数组的前index
PointsSet[row, col + 1] = StartPoint - 1;
//计算子数组个数
Groups++;
//换行记录自然子数组的index
row++;
break;
//--StartPoint;
}
//升序子数组结束index
if (Judge)
PointsSet[row, col] = StartPoint;
//else
// --StartPoint;
} while (StartPoint < Array.Length);
//终于index=StartPoint - 1,可是糟糕情况下还有剩余若干行为: 0,0 ...
PointsSet[row, col + 1] = StartPoint - 1;
//调用展示方法
DisplaySubarray(Array, PointsSet, Groups);
return PointsSet;
}
public void DisplaySubarray(int[] Array, int[,] PointsSet, int Groups)
{
Console.WriteLine("Subarray is {0}:", Groups);
//展示子数组的前后index
for (int r = 0; r < Groups; r++)
{
for (int c = 0; c < PointsSet.GetLength(1); c++)
{
Console.Write(PointsSet[r, c]);
if (c < PointsSet.GetLength(1) - 1)
Console.Write(",");
}
Console.Write("\t\t");
}
Console.WriteLine();
//展示分出的子数组
for (int v = 0; v < Groups; v++)
{
int i = 1;
for (int r = PointsSet[v, 0]; r <= PointsSet[v, 1]; r++)
{
Console.Write(Array[r] + " ");
i++;
}
if (i <= 3)
Console.Write("\t\t");
else
Console.Write("\t");
if (PointsSet[v, 1] == Array.Length)
break;
}
} public void Copy(int[] Array, int[] merge)
{
//一部分排好序的元素替换掉原来Array中的元素
for (int i = 0; i < Array.Length; i++)
{
Array[i] = merge[i];
}
}
//输出
public override string ToString()
{
string temporary = string.Empty; foreach (var element in Array27)
temporary += element + " "; temporary += "\n";
return temporary;
}
} class Program
{
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("请选择:");
Console.WriteLine("1.归并排序(非递归)");
Console.WriteLine("2.归并排序(递归)");
Console.WriteLine("3.归并排序(自然合并)");
Console.WriteLine("4.退出");
int Arraynum = Convert.ToInt32(Console.ReadLine());
switch (Arraynum)
{
case 4:
Environment.Exit(0);
break;
case 1:
Console.WriteLine("Please Input Array Length");
int Leng271 = Convert.ToInt32(Console.ReadLine());
Function obj1 = new Function(Leng271); Console.WriteLine("The original sequence:");
Console.WriteLine(obj1);
Console.WriteLine("'MergeSort' Finaly Sorting Result:");
obj1.ToMergeSort();
Console.WriteLine(obj1);
break;
case 2:
Console.WriteLine("Please Input Array Length");
int Leng272 = Convert.ToInt32(Console.ReadLine());
Function obj2 = new Function(Leng272); Console.WriteLine("The original sequence:");
Console.WriteLine(obj2);
Console.WriteLine("'RecursiveMergeSort' Finaly Sorting Result:");
obj2.ToRecursiveMergeSort();
Console.WriteLine(obj2);
break;
case 3:
Console.WriteLine("Please Input Array Length");
int Leng273 = Convert.ToInt32(Console.ReadLine());
Function obj3 = new Function(Leng273); Console.WriteLine("The original sequence:");
Console.WriteLine(obj3);
obj3.ToNaturalMergeSort();
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("'NaturalMergeSort' Finaly Sorting Result:");
Console.WriteLine(obj3);
break;
}
}
}
}
}

基数排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Merge
{
public class RadixSorter
{
//基数排序
public int[] RadixSort(int[] ArrayToSort, int digit)
{
//low to high digit
for (int k = 1; k <= digit; k++)
{
//temp array to store the sort result inside digit
int[] tmpArray = new int[ArrayToSort.Length];
//temp array for countingsort
int[] tmpCountingSortArray = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//CountingSort
for (int i = 0; i < ArrayToSort.Length; i++)
{
//split the specified digit from the element
int tmpSplitDigit = ArrayToSort[i] / (int)Math.Pow(10, k - 1) - (ArrayToSort[i] / (int)Math.Pow(10, k)) * 10;
tmpCountingSortArray[tmpSplitDigit] += 1;
}
for (int m = 1; m < 10; m++)
{
tmpCountingSortArray[m] += tmpCountingSortArray[m -
1];
}
//output the value to result
for (int n = ArrayToSort.Length - 1; n >= 0; n--)
{
int tmpSplitDigit = ArrayToSort[n] / (int)Math.Pow(10, k - 1) -
(ArrayToSort[n] / (int)Math.Pow(10, k)) * 10;
tmpArray[tmpCountingSortArray[tmpSplitDigit] - 1] = ArrayToSort
[n];
tmpCountingSortArray[tmpSplitDigit] -= 1;
}
//copy the digit-inside sort result to source array
for (int p = 0; p < ArrayToSort.Length; p++)
{
ArrayToSort[p] = tmpArray[p];
}
}
return ArrayToSort;
}
} class Program
{
static void Main(string[] args)
{
int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 };
int[] newIntArray = intArray;
RadixSorter rS=new RadixSorter();
newIntArray = rS.RadixSort(intArray, intArray.Length);
foreach (int i in intArray)
{
Console.Write(i + " ");
}
Console.ReadKey();
}
}
}

计数排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Merge
{
class Program
{
/// <summary>
/// 计数排序。 /// 要求:
/// arrayToSort的元素必须大于等于0。或者经过一定的转换使其元素在
/// 大于等于0范围内。比如有例如以下序列(-1,-8,10,11),那么依据最小值8,
/// 将各个数字加8转化为(7,0,18,19),然后进行计数排序。结果为(0,7,18,19),
/// 然后再将结果个数字减8即为(-8,-1,10,11)
/// </summary>
/// <param name="arrayToSort">要排序的数组</param>
/// <param name="maxValue">数组的最大值加一</param>
/// <returns>计数排序后的结果</returns>
public static int[] CountingSort(int[] arrayToSort, int k)
{
// 排序后的结果存储
int[] sortedArray = new int[arrayToSort.Length];
// 计数数组
int[] countingArray = new int[k];
// 计数数组初始化
for (int i = 0; i < countingArray.Length; i++)
{
countingArray[i] = 0;
} // 单个元素计数(经过该步骤countingArray[i]的含义为数字i的个数为countingArray[i])
for (int i = 0; i < arrayToSort.Length; i++)
{
countingArray[arrayToSort[i]] = countingArray[arrayToSort[i]] + 1;
}
// 计算小于等于某数的个数(经过该步骤countingArray[i]的含义为小于等于数字i的元素个数为countingArray[i])
for (int i = 1; i < countingArray.Length; i++)
{
countingArray[i] += countingArray[i - 1];
} // 得到排序后的结果
for (int i = 0; i < sortedArray.Length; i++)
{
int numIndex = countingArray[arrayToSort[i]] - 1;
sortedArray[numIndex] = arrayToSort[i];
countingArray[arrayToSort[i]] = countingArray[arrayToSort[i]] - 1;
} return sortedArray;
} static void Main(string[] args)
{
int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 };
int[] intNewArray = intArray;
intNewArray = CountingSort(intArray, intArray.Length);
foreach (int i in intNewArray)
{
Console.Write(i + " ");
}
Console.ReadKey();
}
}
}

堆排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Merge
{
class Program
{
//堆排序算法(传递待排数组名,即:数组的地址。故形參数组的各种操作反应到实參数组上)
private static void HeapSortFunction(int[] array)
{
try
{
BuildMaxHeap(array); //创建大顶推(初始状态看做:总体无序)
for (int i = array.Length - 1; i > 0; i--)
{
Swap(ref array[0], ref array[i]); //将堆顶元素依次与无序区的最后一位交换(使堆顶元素进入有序区)
MaxHeapify(array, 0, i); //又一次将无序区调整为大顶堆
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
} ///<summary>
/// 创建大顶推(根节点大于左右子节点)
///</summary>
///<param name="array">待排数组</param>
private static void BuildMaxHeap(int[] array)
{
try
{
//依据大顶堆的性质可知:数组的前半段的元素为根节点,其余元素都为叶节点
for (int i = array.Length / 2 - 1; i >= 0; i--) //从最底层的最后一个根节点開始进行大顶推的调整
{
MaxHeapify(array, i, array.Length); //调整大顶堆
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
} ///<summary>
/// 大顶推的调整过程
///</summary>
///<param name="array">待调整的数组</param>
///<param name="currentIndex">待调整元素在数组中的位置(即:根节点)</param>
///<param name="heapSize">堆中全部元素的个数</param>
private static void MaxHeapify(int[] array, int currentIndex, int heapSize)
{
try
{
int left = 2 * currentIndex + 1; //左子节点在数组中的位置
int right = 2 * currentIndex + 2; //右子节点在数组中的位置
int large = currentIndex; //记录此根节点、左子节点、右子节点 三者中最大值的位置 if (left < heapSize && array[left] > array[large]) //与左子节点进行比較
{
large = left;
}
if (right < heapSize && array[right] > array[large]) //与右子节点进行比較
{
large = right;
}
if (currentIndex != large) //假设 currentIndex != large 则表明 large 发生变化(即:左右子节点中有大于根节点的情况)
{
Swap(ref array[currentIndex], ref array[large]); //将左右节点中的大者与根节点进行交换(即:实现局部大顶堆)
MaxHeapify(array, large, heapSize); //以上次调整动作的large位置(为此次调整的根节点位置),进行递归调整
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
} ///<summary>
/// 交换函数
///</summary>
///<param name="a">元素a</param>
///<param name="b">元素b</param>
private static void Swap(ref int a, ref int b)
{
int temp = 0;
temp = a;
a = b;
b = temp;
} static void Main(string[] args)
{
int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 };
HeapSortFunction(intArray);
foreach (int i in intArray)
{
Console.Write(i + " ");
}
Console.ReadKey();
}
}
}

排序的分类/稳定性/时间复杂度和空间复杂度总结



版权声明:本文博客原创文章。博客,未经同意,不得转载。

C# 经典排序算法大全的更多相关文章

  1. C#字符串数组排序 C#排序算法大全 C#字符串比较方法 一个.NET通用JSON解析/构建类的实现(c#) C#处理Json文件 asp.net使用Jquery+iframe传值问题

    C#字符串数组排序   //排序只带字符的数组,不带数字的 private   string[]   aa   ={ "a ", "c ", "b & ...

  2. 经典排序算法 – 插入排序Insertion sort

    经典排序算法 – 插入排序Insertion sort  插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕. 插入排序方法分直接插入排序和折半插入排序两种, ...

  3. 经典排序算法总结与实现 ---python

    原文:http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/ 经典排序算法在面试中占有很大的比重,也是基础,为了未雨绸缪,在寒假里整理并用P ...

  4. 经典排序算法及python实现

    今天我们来谈谈几种经典排序算法,然后用python来实现,最后通过数据来比较几个算法时间 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据 ...

  5. 经典排序算法 - 基数排序Radix sort

    经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是须要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,临时忽视十位数 比如 待排序数组[ ...

  6. 经典排序算法 - 高速排序Quick sort

    经典排序算法 - 高速排序Quick sort 原理,通过一趟扫描将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据都要小,然后再按此方法对这两部分数据分别进行高速排序,整 ...

  7. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  8. Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现

    2017年4月29日~5月1日,国际劳动节, 三天的小长假. 在国内,小长假往往是这样的: 然而我当时在戏称为"德村"(德国农村)的Walldorf出差并且住在Wiesloch, ...

  9. 【最全】经典排序算法(C语言)

    算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...

随机推荐

  1. sqlserver安全加固

      sqlserver2012安装好以后必要的安全加固,不然非常多DBA的信息普通账户登录后都能够读取到.  --use [master] --GO --DENY VIEW SERVER STATE ...

  2. libgdx如何调用android平台内容

    使用libgdx已经有一段时间了.最近经常有朋友问我如何在libgdx中调用android的内容. 正常来说libgdx是跨平台的,gdx中的代码是不允许有任何其他平台的相关代码,但实际使用时经常会有 ...

  3. As long as Binbin loves Sangsang

    题目连接 题意: 给定一个无向图,每一个边有两个属性.长度和一个字母'L','O','V'.'E'中的一个.从1点開始到达n点,每次必须依照L -> O -> V -> E -> ...

  4. Cocos2d-x3.1 粒子效果演示样例

    这里把粒子的几种效果粘出来,以便以后使用 原文地址:http://blog.csdn.net/qqmcy/article/details/37511259 // // IntervalLayer.cp ...

  5. vps自己搭建VPN(转)

    1.购买一个VPS: https://www.pzea.com/North-America-openvz-vps.html 2.下载putty软件,进行vpn安装: http://www.chiark ...

  6. friend keyword 对于模板 并不只不过友元!!!

    friend是C++中封装的漏网之鱼. C++中的friend同意其它的类或者是函数訪问本类的不论什么成员.甚至是private成员,仅仅要该类声明其为友元. 但是,在有些情况下,并非同意外界訪问类的 ...

  7. URAL 1934 Black Spot --- 最短的简单修改

    右侧是1.维护的同时保持最短路p值至少,我有直接存款(1-p).该概率不满足,为了使这个值极大. #include <iostream> #include <cstdlib> ...

  8. 完全合并C++面试题

    C++面试题 1.是不是父母写了virtual 功能,假设子类重写它的功能不virtual ,也使多态性? virtual修饰符隐形遗传. private 还集成.问权限而已 virtual可加可不加 ...

  9. SSH三作品的框架和流程

    Hibernate工作的,为什么? 原理: 1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件 2.由hibernate.cfg.xm ...

  10. Test SRM Level One: TemperatureScales

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=6038 因为TopCoder SRM比赛使用的编译器进行了升级, ...