.NET算法集
1. 选择排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespacesorter
{
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 = newSelectionSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}
2. 冒泡排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespacesorter
{
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 = newEbullitionSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}
3. 快速排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespacesorter
{
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], reflist[high]);
}
return;
}
mid = (low + high) >> 1;
pivot = list[mid];
swap(ref list[low], reflist[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], reflist[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 = newQuickSorter();
selSor.Sort(arrInt, 0,arrInt.Length - 1);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}
4. 插入排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespacesorter
{
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 = newInsertionSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}
5. 希尔排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespacesorter
{
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 = newShellSorter();
selSor.Sort(arrInt);
foreach (int i in arrInt)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}
6. 归并排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceMerge
{
public class Function
{
private int Groups;
private int CopyGroups;
private int mergerows;
private int[] Array27;
private static Random ran = newRandom();
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>
/// <paramname="Array"></param>
/// <paramname="left"></param>
/// <paramname="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, intleft, 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>
/// <paramname="Array"></param>
public void MergeSort(int[] Array)
{
//index固定的数组
int[] merge = newint[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 = newint[Array.Length];
//循环取每个自然子数组的index
while (true)
{
// int Temprow = 1;
//只记录合并后的子数组(”《应该为》“动态的)
int[,] TempPointsSymbol = newint[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 = newint[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 inArray27)
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 = newFunction(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 = newFunction(Leng272);
Console.WriteLine("The original sequence:");
Console.WriteLine(obj2);
Console.WriteLine("'RecursiveMergeSort' Finaly SortingResult:");
obj2.ToRecursiveMergeSort();
Console.WriteLine(obj2);
break;
case 3:
Console.WriteLine("Please Input Array Length");
int Leng273 =Convert.ToInt32(Console.ReadLine());
Function obj3 = newFunction(Leng273);
Console.WriteLine("The originalsequence:");
Console.WriteLine(obj3);
obj3.ToNaturalMergeSort();
Console.WriteLine();Console.WriteLine();
Console.WriteLine("'NaturalMergeSort'Finaly Sorting Result:");
Console.WriteLine(obj3);
break;
}
}
}
}
}
7. 基数排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceMerge
{
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 sortresult inside digit
int[] tmpArray = newint[ArrayToSort.Length];
//temp array forcountingsort
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 digitfrom 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 sortresult 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=newRadixSorter();
newIntArray = rS.RadixSort(intArray,intArray.Length);
foreach (int i in intArray)
{
Console.Write(i + "");
}
Console.ReadKey();
}
}
}
8. 计数排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceMerge
{
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>
/// <paramname="arrayToSort">要排序的数组</param>
/// <paramname="maxValue">数组的最大值加一</param>
/// <returns>计数排序后的结果</returns>
public static int[] CountingSort(int[]arrayToSort, int k)
{
// 排序后的结果存储
int[] sortedArray = newint[arrayToSort.Length];
// 计数数组
int[] countingArray = newint[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();
}
}
}
9. 堆排序
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceMerge
{
class Program
{
//堆排序算法(传递待排数组名,即:数组的地址。故形参数组的各种操作反应到实参数组上)
private static void HeapSortFunction(int[]array)
{
try
{
BuildMaxHeap(array); //创建大顶推(初始状态看做:整体无序)
for (int i = array.Length - 1;i > 0; i--)
{
Swap(ref array[0], refarray[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>
///<paramname="currentIndex">待调整元素在数组中的位置(即:根节点)</param>
///<paramname="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(refarray[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, refint 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();
}
}
}
排序的分类/稳定性/时间复杂度和空间复杂度总结
10. 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
class sq
{
static public void Main()
{
double x;
double y;
for (int i = 1; i < 100000; i++)
{
x = Math.Sqrt(i + 100);
y = Math.Sqrt(i + 100 + 168);
if (x * x == i + 100 &&y * y == i + 268)
{
Console.Write(i + "\t");
}
}
Console.ReadKey();
}
}
11. 输入某年某月某日,判断这一天是这一年的第几天?
classdaytime
{
static void Main()
{
Console.Write("输入你要查询的日期\n");
int year =int.Parse(Console.ReadLine());
int mooth =int.Parse(Console.ReadLine());
int day =int.Parse(Console.ReadLine());
int sum = 0;
if ((year % 4 == 0 && year% 100 != 0) || (year % 400 == 0))
{
if (mooth > 1)
{
sum += getday(mooth) + 1 +day;
}
else
{
sum = day;
}
}
else
{
sum = getday(mooth) + day;
}
Console.WriteLine("***********");
Console.Write("这是本年度的第" + sum + "天\n");
Console.WriteLine("***********");
Console.ReadKey();
}
public static int getday(int y)
{
int[] a = new int[13];
a[0] = 0;
a[1] = a[3] = a[5] = a[7] = a[8] =a[9] = a[10] = a[12] = 31;
a[2] = 28;
a[4] = a[6] = a[9] = 30;
int sum = 0;
for (int i = 0; i < y; i++)
{
sum += a[i];
}
return sum;
}
}
12. 输入三个整数x,y,z,请把这三个数由小到大输出。
classcompare
{
public static void Main()
{
Console.WriteLine("输入你要比较的三个值:\n");
int x =int.Parse(Console.ReadLine());
int y =int.Parse(Console.ReadLine());
int z =int.Parse(Console.ReadLine());
int t = 0;
if (x > y)
{
t=y;
y = x;
x = t;
}
if (x > z)
{
t= z;
z = x;
x = t;
}
if (y > z)
{
t= z;
z = y;
y = t;
}
Console.Write(x+""+y+" "+z+" ");
Console.ReadKey();
}
}
13. 输出9*9口诀。
classchengfabiao
{
public static void Main()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
Console.Write(i +"*" + j + "=" + i * j+" ");
}
Console.WriteLine("\n");
}
}
}
14. 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
class 斐波那契数列
{
public static void Main()
{
int f1, f2;
f1 = f2 = 1;
int f3;
int i = 0;
while (i <= 20)
{
f3 = f1 + f2;
i++;
Console.Write(" " +f3);
f1 = f2;
f2 = f3;
if (i % 5 == 0)
{
Console.WriteLine("\n");
}
}
Console.ReadKey();
}
}
15. 判断101-200之间有多少个素数,并输出所有素数。
classoptinons
{
public static void Main()
{
bool flag=false;
int i; int h = 0;
int j;
for(i=101;i<=200;i++)
{
flag=true;
for (j = 2; j <= i / 2;j++ )
{
if (i % j == 0)
{
flag = false;
break;
}
}
if(flag==true)
{
Console.Write(" "+i);
h++;
}
}
Console.Write("\n"+"h="+h);
}
}
16. 打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数
classshuixianhua
{
public static void Main()
{
int i, j, k;
int h = 0;
for (int n = 100; n < 1000; n++)
{
i = n / 100;
j = n / 10 % 10;
k = n % 10;
if (Math.Pow(i, 3) +Math.Pow(j, 3) + Math.Pow(k, 3) == n)
{
Console.Write(" " + n);
h++;
if (h % 5 == 0)
{
Console.WriteLine("\n");
}
}
}
}
}
17. 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222
classmaths
{
public static void Main()
{
int h = 0;
Console.Write("输入你要加的位数:");
int d =int.Parse(Console.ReadLine());
Console.Write("输入你要算的数***例如5:");
int b =int.Parse(Console.ReadLine());
double i = 0;
int f = 0;
while (i <=d)
{
h += b; f += h;
b*=10;
++i;
}
Console.Write("h=" + f);
}
}
18. 利用碾乘法计算最大公约数最小公倍数
classNium
{
public static void Main()
{
Console.WriteLine("输入你要比较的两个的两个数:");
int num1 =int.Parse(Console.ReadLine());
int num2 =int.Parse(Console.ReadLine());
int temp;
if (num1 < num2)
{
temp = num1;
num1 = num2;
num2 = temp;
}
int a, b;
a = num1;
b = num2;
while(b != 0)
{
temp = a % b;
a = b;
b = temp;
}
Console.Write("最大公约数b=" + a);
Console.Write("最小公倍数a=" + num1 * num2 / a);
Console.ReadKey();
}
}
19. 一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
classgrivaly
{
public static void Main()
{
double h = 100;
double sum=0;
for (int i = 1; i <= 10; i++)
{
sum += h * 2;
h /= 2;
}
Console.Write("第十次的时候小球落地的高度是h=" + h);
Console.Write("总共经过了" + sum + 100);
}
}
20. 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个,
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
classpeach
{
public static void Main()
{
int x1=0;
int x2 = 1;
int day = 9;
while (day > 0)
{
x1 = (x2 + 1) * 2;
x2 = x1;
day--;
}
Console.Write("桃子的总数是:" + x1);
}
}
classpeach2
{
public static void Main()
{
int x1 = 0;
int x2 = 1;
for (int day = 9; day > 0;day--)//第一天的桃子总数等于第二天的桃子总数+1的2倍
{
x1 = (x2 + 1) * 2;
x2 = x1;
}
Console.Write("桃子的总数是:" + x1);
}
}
21. 打印出如下图案(菱形)
///*
///***
///*****
///*******
///*****
///***
///*
///
classdevice
{
public static void Main()
{
for (int i = 0; i <= 4; i++)
{
for (int j = 1; j <= 2 * i- 1; j++)
{
Console.Write("*");
}
Console.Write("\n");
}
for (int i = 3; i>0; i--)
{
for (int j = 1; j<=2*i-1 ;j++)
{
Console.Write("*");
}
Console.Write("\n");
}
}
}
22. 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
classfeibo
{
public static void Main()
{
int a = 1;
int b = 2;
double t = 0;
int c;
for (int i = 1; i < 20; i++)
{
t += b / a;
c= a;
a += b;
b = c;
}
Console.Write("2/1,3/2,5/3,8/5,13/8,21/13...的前20项之和等于" + t+"\n");
}
}
23. 求1+2!+3!+...+20!的和
classjiecheng
{
public static void Main()
{
int h = 0; ;
for(int i=1;i<=20;i++)
{
h += Fact(i);
}
Console.Write("1+2!+3!+...+20!=" + h);
}
public static int Fact(int i)
{
int sum = 1;
for (int n = 1; n <= i; n++)
{
sum *= n;
}
return sum;
}
}
classjiecheng
{
public static void Main()
{
int sum=0;
int h=1;
for(int i=1;i<=20;i++)
{
h*=i;
sum+=h;
}
Console.Write("sum="+sum);
}
}*
24. 递归算法(求1+2!+3!+...+20!的和)
class die
{
public static void Main()
{
int h=0;
for (int i = 1; i <= 20; i++)
{
h += fact(i);
}
Console.WriteLine(h);
}
public static int fact(int i)
{
int sum=0;
if (i == 0)
return sum = 1;
else
return i * fact(i - 1);
}
}
25. 利有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?
classages
{
public static void Main()
{
Console.Write(age(5));
}
public static int age(int a)
{
int ag = 0;
if (a == 1)
return ag = 10;
else
return age(a - 1) + 2;
}
}
26. 逆序输出string 字符串
classputs
{
public static void Main()
{
Console.WriteLine("输入你要逆序输出的字符串:");
string s = Console.ReadLine();
for(int i=s.Length-1;i>=0;i--)
{
Console.Write(s[i]);
}
}
}
27. 二维数组对角线和计算
classsum// 问题(二维数组的输入)
{
public static void Main()
{
int[,] a = new int[3, 3];
Console.WriteLine("输入这个二维数组");
int h=a.Length;
// Console.Write(h);
for (int i = 0; i <3 ; i++)
{
for (int j = 0; j<3; j++)
{
a[i,j] =int.Parse(Console.ReadLine());
}
}
for (int i = 0; i <3; i++)
{
for (int j = 0; j< 3; j++)
{
Console.Write(a[i, j]);
}
}
}
}
28. 加密
classjiami
{
public static void Main()
{
char[] a = new char[10];
Console.Write("输入你要加密的字符串:\n");
for (int i = 0; i < a.Length;i++)
{
a[i] =(char)(Convert.ToChar(Console.ReadLine()) + i);
}
Console.WriteLine("");
Console.Write("加密后的数组是:");
for (int i = 0; i < a.Length;i++)
{
Console.Write(" " +a[i]);
}
Console.Write("\n还原后的数组是:");
for (int i = 0; i < a.Length;i++)
{
Console.Write(" " +(char)(a[i] - i));
}
string s;
Console.WriteLine("输入你要加密的字符");
s = Console.ReadLine();
char[] b = new char[s.Length];
int n=0;
foreach (char c in s)
{
b[n] =(char)(c+99);
n++;
}
for (int i = 0; i < s.Length;i++)
{
Console.Write(b[i]);
}
}
}
29. 求以下表达式的值,写出您想到的一种或几种实现方法:1-2+3-4+……+m
staticint F1(int m)
{
int sum =0;
bool flag =true;
for (int i = 1; i <= m; i++)
{
if (flag) //一次是默认是True,下下也为True
sum += i;
else
sum -= i;
flag = !flag;
}
return sum;
}
//通过奇偶性
static int F2(int m)
{
int sum = 0;
for (int i = 1; i <= m; i++)
{
if (i % 2 >0) //即为奇数
sum += i;
else
sum -= i;
}
return sum;
}
30. 有一个字符串 "I am a good man",设计一个函数,返回 "man good a am I"。
staticstring Reverse()
{
string s = "I am a goodman";
string[] arr = s.Split(' ');
string res = "";
for (int i = arr.Length - 1; i>= 0; i--)
{
res += arr[i];
if (i > 0)
res += " ";
}
return res;
}
31. 有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
classProgram
{
static void Main(string[] args)
{
//有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
//分解题目
//条件:四个数字1、2、3、4 ;三位数:百位、十位、个位
//要求:互不相同;无重复数字:每个数字在三位中只出现一次
//结果:多少个? 都是多少?
int count = 0; //统计个数
for (int bw = 1; bw <= 4;bw++)
{
for (int sw = 1; sw <= 4;sw++)
{
if (sw!= bw) //很显然,只有百位和十位不同的情况下才能谈个位。
{
for (int gw = 1; gw<= 4; gw++)
{
if (gw != sw&& gw != bw) //百位用过的,十位就不能用;百位和十位都用过的,个位就不能用
{
count++;
Console.WriteLine("{0}{1}{2}",bw, sw, gw);
}
}
}
}
}
Console.WriteLine("一共有{0}个", count);
Console.Read();
}
}