c#实现常用排序算法
让我们先看一看常用排序算法的效率对比
接着请看代码和注释~
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplicationAlgorithm
{
interface ISortAlgorithm
{
/// <summary>
/// 排序
/// </summary>
/// <param name="a">数组</param>
/// <param name="n">数组长度</param>
void Sort(int[] a, int n);
}
#region 直接插入排序
public class StraightInsertionSort : ISortAlgorithm
{
//直接插入排序(straight insertion sort)的作法是:
//每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
//第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
//直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。
//值得注意的是,我们必需用一个存储空间来保存当前待比较的数值,因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位 插入排序类似玩牌时整理手中纸牌的过程。插入排序的基本方法是:每步将一个待排序的记录按其关键字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止。
public void Sort(int[] a, int n)//直接插入排序属于稳定的排序,最好情况O(n),最坏时间复杂性为Θ(n^2),平均时间O(n^2),空间复杂度为O(1)。
{
int i;
int j;
int temp;
for (i = 1; i < n; i++)
{
Console.WriteLine("第{0}遍排序,即从第{1}个数开始", (i).ToString(), (i + 1).ToString());
temp = a[i];
//只要大于前一个则跳出循环,因为在此之前的序列肯定有序的
for (j = i; j > 0; j--)
{
if (temp > a[j - 1])
{
Console.WriteLine("由于{0}>{1}所以跳出排序", temp.ToString(), a[j - 1].ToString());
break;
}
a[j] = a[j - 1];
}
Console.WriteLine("在下标为{0}处元素插入{1},第{2}个元素前有序", (j).ToString(), temp.ToString(), (i + 1).ToString());
a[j] = temp;
Helper.Print(a, n);
}
}
}
#endregion
#region 插入排序
//冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。 由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。 用二重循环实现,外循环变量设为i,内循环变量设为j。假如有10个数需要进行排序,则外循环重复9次,内循环依次重复9,8,...,1次。每次进行比较的两个元素都是与内循环j有关的,它们可以分别用a[j]和a[j+1]标识,i的值依次为1,2,...,9,对于每一个i,j的值依次为1,2,...10-i。
public class Bubblesort : ISortAlgorithm
{
public void Sort(int[] a, int n)//冒泡排序属于稳定的排序,最好情况O(n),最坏时间复杂性为O(n^2),平均时间O(n^2),空间复杂度为O(1)。
{
int temp;
for (int i = 0; i < a.Length - 1; i++)
{
Console.WriteLine("第{0}遍排序,由于{0}个元素前有序,所以到第{0}个元素结束", (i + 1).ToString());
//从后往前比较
for (int j = a.Length - 1; j > i; j--)
{
//如果小于前面一个则交换,否则不动
if (a[j] < a[j - 1])
{
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
Console.WriteLine("第{0}与第{1}个元素交换", (j + 1).ToString(), j.ToString());
Helper.Print(a, n);
}
else
{
Console.WriteLine("不用移动");
}
}
}
}
}
#endregion
#region 选择排序
// n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:
//①初始状态:无序区为R[1..n],有序区为空。
//②第1趟排序
//在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
//……
//③第i趟排序
//第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
//这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。
//常见的选择排序细分为简单选择排序、树形选择排序(锦标赛排序)、堆排序。上述算法仅是简单选择排序的步骤。
public class SelectSort : ISortAlgorithm//选择排序属于不稳定的排序,最好情况O(n^2),最坏时间复杂性为O(n^2),平均时间O(n^2),空间复杂度为O(1)。
{
public void Sort(int[] a, int n)
{
int temp = 0;
int minIndex;
for (int i = 0; i < n - 1; i++)
{
Console.WriteLine("第{0}遍排序", (i + 1).ToString());
Console.WriteLine("从第{0}处开始比较", (i + 1).ToString());
minIndex = i;
for (int j = i + 1; j < n; j++)
{
if (a[j] < a[minIndex])
{
temp = a[j];
minIndex = j;
}
}
if (a[minIndex] != a[i])
{
Console.WriteLine("选择第{0}最小的元素{1}与第{2}元素交换", (minIndex + 1).ToString(), a[minIndex].ToString(), (i + 1).ToString());
a[minIndex] = a[i];
a[i] = temp;
}
Helper.Print(a, a.Length);
}
}
}
#endregion
#region 希尔排序
//希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
//希尔排序是基于插入排序的以下两点性质而提出改进方法的:
// 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
// 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
//先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。 该方法实质上是一种分组插入方法。 比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除 多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。 一般的初次取序列的一半为增量,以后每次减半,直到增量为1。 给定实例的shell排序的排序过程 假设待排序文件有10个记录,其关键字分别是: 49,38,65,97,76,13,27,49,55,04。 增量序列的取值依次为: 5,3,1
// 已知的最好步长序列由Marcin Ciura设计(1,4,10,23,57,132,301,701,1750,…) 这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”用这样步长序列的希尔排序比插入排序和堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。
//另一个在大数组中表现优异的步长序列是(斐波那契数列除去0和1将剩余的数以黄金分割比的两倍的幂进行运算得到的数列):(1, 9, 34, 182, 836, 4025, 19001, 90358, 428481, 2034035, 9651787, 45806244, 217378076, 1031612713, …)[2]
public class ShellSort : ISortAlgorithm//希尔排序属于不稳定的排序平均时间O(n^1.25),空间复杂度为O(1)。
{
public void Sort(int[] a, int n)
{
for (int gap = n / 2; gap > 0; gap /= 2)
{
Console.WriteLine("增量为{0}进行直接插入排序", gap);
for (int i = gap; i < n; i++)
{
int key = a[i];
int j = 0;
//此处实现插入排序
for (j = i - gap; j >= 0; j -= gap)
{
if (a[j] > key)
{
Console.WriteLine("由于{0}>{1}交换{2}和{3}处的数据", a[j].ToString(), key.ToString(), j.ToString(), (j + gap).ToString());
a[j + gap] = a[j];
}
else
{
Console.WriteLine("由于{0}<{1},不发生交换", a[j].ToString(), key.ToString());
break;
}
}
a[j + gap] = key;
Helper.Print(a, n);
}
}
Helper.Print(a, n);
}
}
#endregion
#region 并归排序
//归并操作的过程如下:
//申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
//设定两个指针,最初位置分别为两个已经排序序列的起始位置
//比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
//重复步骤3直到某一指针达到序列尾
//将另一序列剩下的所有元素直接复制到合并序列尾
public class MergeSort : ISortAlgorithm//并归排序属于稳定的排序,最好情况O(nlgn),最坏时间复杂性为O(nlgn),平均时间O(nlgn),空间复杂度为O(n)。
{
public void Sort(int[] a, int n)
{
int[] temp = new int[n];
mergeSort(a, temp, 0, n - 1);
Helper.Print(a, n);
}
void Merge(int[] r, int[] r1, int low, int mid, int high)
{
int i = low; int j = mid + 1; int k = low;
while (i <= mid && j <= high)
{
if (r[i] <= r[j])
{
Console.WriteLine("由于{0}<{1},临时空间{2}处赋值{3}", r[i].ToString(), r[j].ToString(), k.ToString(), r[i].ToString());
r1[k++] = r[i++];
}
else
{
Console.WriteLine("由于{0}>{1},临时空间{2}处赋值{3}", r[i].ToString(), r[j].ToString(), k.ToString(), r[j].ToString());
r1[k++] = r[j++];
}
}
if (i <= mid)
{
Console.WriteLine("由于左边还有数字没有赋值到临时空间,已经有序,直接赋值");
while (i <= mid)
{
Console.WriteLine("在{0}处赋值{1}", k.ToString(), r[i].ToString());
r1[k++] = r[i++];
}
}
else
{
Console.WriteLine("由于右边还有数字没有赋值到临时空间,已经有序,直接赋值");
while (j <= high)
{
Console.WriteLine("在{0}处赋值{1}", k.ToString(), r[j].ToString());
r1[k++] = r[j++];
}
}
Helper.Print(r1, r1.Length);
Console.WriteLine("将临时空间的值赋值给真实的空间");
for (int l = 0; l < high + 1; l++)
r[l] = r1[l];
}
void mergeSort(int[] r, int[] r1, int low, int high)
{
if (low != high)
{
int mid = (low + high) / 2;
Console.WriteLine("从{0}-{1}处分治", low.ToString(), mid.ToString());
mergeSort(r, r1, low, mid);
Helper.Print(r, r.Length);
Console.WriteLine("从{0}-{1}处分治", (mid + 1).ToString(), high.ToString());
mergeSort(r, r1, mid + 1, high);
Helper.Print(r, r.Length);
Console.WriteLine("从{0}-{1}与{2}-{3}处合并", low.ToString(), mid.ToString(), (mid + 1).ToString(), high.ToString());
Merge(r, r1, low, mid, high);
}
}
}
#endregion
#region 堆排序
//堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
//通常堆是通过一维数组来实现的。在起始数组为 0 的情形中:
//父节点i的左子节点在位置 (2*i+1);
//父节点i的右子节点在位置 (2*i+2);
//子节点i的父节点在位置 floor((i-1)/2);
//在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义以下几种操作:
//最大堆调整(Max_Heapify):将堆的末端子结点作调整,使得子结点永远小于父结点
//创建最大堆(Build_Max_Heap):将堆所有数据重新排序
//堆排序(HeapSort):移除位在第一个数据的根结点,并做最大堆调整的递归运算
public class Heapsort : ISortAlgorithm//并归排序属于稳定的排序,最好情况O(nlgn),最坏时间复杂性为O(nlgn),平均时间O(nlgn),空间复杂度为O(n)。
{
public void Sort(int[] a, int n)
{
Helper.PrintTree(a, n, (int)Math.Log(n, 2), 0);
heap_sort(a, n);
Helper.Print(a, n);
}
void sift(int[] d, int ind, int len)
{
//#置i为要筛选的节点#%
int i = ind;
Console.WriteLine("选择节点{0}", d[i].ToString());
//#c中保存i节点的左孩子#%
int c = i * 2 + 1; //#+1的目的就是为了解决节点从0开始而他的左孩子一直为0的问题#%
if (c > len)
{
Console.WriteLine("节点{0}没有子孩子,跳出", d[i].ToString());
}
while (c < len)//#未筛选到叶子节点#%
{
Console.WriteLine("选择左孩子{0}", d[c].ToString());
//#如果要筛选的节点既有左孩子又有右孩子并且左孩子值小于右孩子#%
//#从二者中选出较大的并记录#%
if (c + 1 < len && d[c] < d[c + 1])
{
c++;
}
Console.WriteLine("左孩子,右孩子中选出最大的孩子{0}", d[c].ToString());
//#如果要筛选的节点中的值大于左右孩子的较大者则退出#%
if (d[i] > d[c])
{
Console.WriteLine("选择节点{0}大于他的最大孩子{1},跳出", d[i].ToString(), d[c].ToString());
break;
}
else
{
Console.WriteLine("选择节点{0}小于他的最大孩子{1},交换", d[i].ToString(), d[c].ToString());
//#交换#%
int t = d[c];
d[c] = d[i];
d[i] = t;
Helper.PrintTree(d, len, (int)Math.Log(len, 2), 0);
i = c;
c = 2 * i + 1;
if (c < len)
{
Console.WriteLine("重置要筛选的节点为{0}和要筛选的左孩子为{1}", d[i].ToString(), d[c].ToString());
}
else
{
Console.WriteLine("重置要筛选的节点为{0},没有孩子", d[i].ToString());
}
}
}
return;
}
void heap_sort(int[] d, int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
{
Console.WriteLine("初始化建堆, {0}从最后一个非叶子节点开始", i.ToString());
sift(d, i, n);
Helper.PrintTree(d, n, (int)Math.Log(n, 2), 0);
}
Console.WriteLine("开始排序");
for (int i = 0; i < n; i++)
{
//#交换#%
int t = d[0];
d[0] = d[n - i - 1];
d[n - i - 1] = t;
Console.WriteLine("交换元素{0}和{1},将最大元素放在最后面,交换之后的元素后面有序", d[0].ToString(), t.ToString());
Helper.PrintTree(d, n, (int)Math.Log(n, 2), 0);
//#筛选编号为0 #%
sift(d, 0, n - i - 1);
Helper.PrintTree(d, n, (int)Math.Log(n, 2), 0);
}
}
}
#endregion
#region 快速排序
//快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
// 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
//步骤为:
//从数列中挑出一个元素,称为 "基准"(pivot),
//重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
//递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
//递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
public class Quicksort : ISortAlgorithm//并归排序属于不稳定的排序,最好情况O(nlgn),最坏时间复杂性为O(nlgn),平均时间O(n^2),最好情况是O(n log n)和最坏情况是O(n2 log n)的空间需求。
{
public void Sort(int[] a, int n)
{
Console.WriteLine("自顶向下分治法先从{0},{1}", 0, (n - 1).ToString());
QuickSort(a, 0, n - 1);
Helper.Print(a, n);
}
private static void QuickSort(int[] numbers, int left, int right)
{
if (left < right)
{
int middle = numbers[(left + right) / 2];
Console.WriteLine("选择基准数{0}", middle.ToString());
int i = left - 1;
int j = right + 1;
while (true)
{
if (numbers[i + 1] >=middle)
{
Console.WriteLine("{0}大于=基准数,下标不变,跳出向后循环", numbers[i + 1].ToString());
}
while (numbers[++i] < middle)
{
Console.WriteLine("{0}小于基准数,下标后移", numbers[i].ToString());
};
while (numbers[--j] > middle)
{
Console.WriteLine("{0}大于基准数,下标前移", numbers[j].ToString());
};
if (numbers[j] <= middle)
{
Console.WriteLine("{0}小于=基准数,下标不变,跳出向后循环", numbers[j].ToString());
}
if (i >= j)
{
Console.WriteLine("{0}>{1},下标相遇,跳出", i.ToString(), j.ToString());
break;
}
Console.WriteLine("交换{0},{1}", numbers[i].ToString(), numbers[j].ToString());
Swap(numbers, i, j);
Helper.Print(numbers, numbers.Length);
}
Console.WriteLine("自顶向下分治法先从{0},{1}", left, (i - 1).ToString());
QuickSort(numbers, left, i - 1);
Console.WriteLine("自顶向下分治法先从{0},{1}", (j + 1).ToString(), right.ToString());
QuickSort(numbers, j + 1, right);
}
}
private static void Swap(int[] numbers, int i, int j)
{
int number = numbers[i];
numbers[i] = numbers[j];
numbers[j] = number;
}
}
#endregion
static class Helper
{
public static void Print(int[] a, int n)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++)
{
sb.Append(a[i].ToString() + " ");
}
Console.Write(sb.ToString());
Console.WriteLine("\n");
sb.Clear();
}
public static void PrintTree(int[] a, int n, int height, int row)
{
StringBuilder sb = new StringBuilder();
//判断是否深度最大
if (row == (int)Math.Log(n, 2) + 1)
{
return;
}
//增加每一行前空格
for (int i = 0; i < Math.Pow(2, height) - 1; i++)
{
sb.Append(" ");
}
//添加每一行元素
for (int j = (int)Math.Pow(2, row) - 1; (j < Math.Pow(2, row + 1) - 1) && j < n; j++)
{
sb.Append(a[j].ToString());
//每个元素后的空格,等于上一行第一个元素前的空格数
for (int i = 0; i < Math.Pow(2, height + 1) - 1; i++)
{
sb.Append(" ");
}
}
sb.Append("\n");
Console.WriteLine(sb.ToString());
PrintTree(a, n, (height - 1), (row + 1));
}
}
}
Program类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplicationAlgorithm
{
class Program
{
static void Main(string[] args)
{
ISortAlgorithm sort;
bool exist = false;
int[] a;
while (exist == false)
{
a = new int[] { 46, 58, 15, 10, 90, 18, 45, 62 };
Helper.Print(a, a.Length);
Console.WriteLine("请选择排序算法");
Console.WriteLine("1.直接插入排序");
Console.WriteLine("2.冒泡排序(从后往前冒泡)");
Console.WriteLine("3.选择排序");
Console.WriteLine("4.希尔排序");
Console.WriteLine("5.并归排序");
Console.WriteLine("6.堆排序");
Console.WriteLine("7.快速排序");
Console.WriteLine("\n");
ConsoleKeyInfo select = Console.ReadKey();
switch (select.KeyChar)
{
case '1':
{
Console.WriteLine("您选择了直接选择排序:\n");
sort = new StraightInsertionSort();
sort.Sort(a, a.Length);
break;
}
case '2':
{
Console.WriteLine("您选择了冒泡排序:\n");
sort = new Bubblesort();
sort.Sort(a, a.Length);
break;
}
case '3':
{
Console.WriteLine("您选择了选择排序:\n");
sort = new SelectSort();
sort.Sort(a, a.Length);
//exist = true;
break;
}
case '4':
{
Console.WriteLine("您选择了希尔排序:\n");
sort = new ShellSort();
sort.Sort(a, a.Length);
//exist = true;
break;
}
case '5':
{
Console.WriteLine("您选择了并归排序:\n");
sort = new MergeSort();
sort.Sort(a, a.Length);
//exist = true;
break;
}
case '6':
{
Console.WriteLine("您选择了堆排序:\n");
sort = new Heapsort();
sort.Sort(a, a.Length);
//exist = true;
break;
}
case '7':
{
Console.WriteLine("您选择了快速排序:\n");
sort = new Quicksort();
sort.Sort(a, a.Length);
//exist = true;
break;
}
}
Console.WriteLine("\n");
}
}
}
}
c#实现常用排序算法的更多相关文章
- Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...
- 转载部长一篇大作:常用排序算法之JavaScript实现
转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...
- Java 常用排序算法/程序员必须掌握的 8大排序算法
Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 面试中常用排序算法实现(Java)
当我们进行数据处理的时候,往往需要对数据进行查找操作,一个有序的数据集往往能够在高效的查找算法下快速得到结果.所以排序的效率就会显的十分重要,本篇我们将着重的介绍几个常见的排序算法,涉及如下内容: 排 ...
- 常用排序算法java实现
写在前面:纸上得来终觉浅.基本排序算法的思想,可能很多人都说的头头是到,但能说和能写出来,真的还是有很大区别的. 今天整理了一下各种常用排序算法,当然还不全,后面会继续补充.代码中可能有累赘或错误的地 ...
- 我们一起来排序——使用Java语言优雅地实现常用排序算法
破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
- 第四百一十五节,python常用排序算法学习
第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...
- Java常用排序算法及性能测试集合
测试报告: Array length: 20000 bubbleSort : 573 ms bubbleSortAdvanced : 596 ms bubbleSortAdvanced2 : 583 ...
随机推荐
- [转]FreeMarker使用
copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...
- DELPHI XE5 UP2 无真机输出 APP并转换为IPA(实践整理)
1.在Mac上配置开发环境(具体步骤请百度) XCODE5.1+IOS7.1SDK+COMMAND LINE TOOLS 安装PlatformAssistant 买一个真机调试账号(实际测 ...
- 在sql server数据库可以插入在回车的数据
insert into t_FamilyClass (id,ParentId,Name) values(111,111,'111')可以在编辑模式下copy到editplus中,设置 显示 空白字符: ...
- c# 实现点击下载功能
转自百度知道 private void DownLoad(string strName, string strPath) { string fileName = strName;//客户端保存的文件名 ...
- 搜索引擎Hoot的源码阅读(提供源码)
开门见山,最近阅读了一下一款开源引擎的源码,受益良多(学到了一些套路).外加好久没有写博客了(沉迷吃鸡,沉迷想念姑娘),特别开一篇.Hoot 的源码地址, 原理介绍地址.外加我看过之后的注释版本,当然 ...
- form表单以get方式提交时action中?后面的参数部分不生效
form表单的提交方式是get方式,action="?sss=test",问号后面参数是接受不到的,谨记!
- 十、Node.js-url模块
下面使用之前提到过的note交互模式(可以在cmd直接执行js代码)进行学习url模块 跳出note模式同样是Ctrl+C(两次) 学习url模块主要是要掌握url模块的方法: url.parse() ...
- MongoDB 副本集配置,开启账号认证
MongoDB 自带功能强大的主从,配置也很简单,从零开始花了30分钟搞定 3台以上机器IP: 192.168.1.24, 192.168.1.25, 192.168.1.26, 192.168.1. ...
- javascript 数组排序
var arr=[1,2,3,5,10,4,2,19,2,0]; alert(arr);//[1,2,3,5,10,4,2,19,2,0] arr.sort(function (a, b) {//升序 ...
- 洛谷P3254 圆桌问题(最大流)
传送门 一道良心啊……没那么多麻烦了…… 从$S$向所有单位连边,容量为单位人数,从所有桌子向$T$连边,容量为桌子能坐的人数,从每一个单位向所有桌子连边,容量为$1$,然后跑一个最大流,看一看$S$ ...