using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SortFunc
{
class Program
{
static void Main(string[] args)
{
List<int> list = (new int[10] { -23, -77, 6, 123, 43, 76, 84, 213, 78, -56 }).ToList();
//Sort.SelectSort(list);
//Sort.BubbleSort(list);
//Sort.InsertSort(list);
//Sort.QuickSort(list);
//list = Sort.MergeSort(list);
//Sort.HeapSort(list);
//Sort.ShellSort(list);
list = Sort.RadixSort(list);
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
Console.ReadKey();
}
}
class Sort
{
/// <summary>
/// 选择排序
/// 原理:找出数组最大值放在末尾或者最小值放在排头
/// </summary>
/// <param name="list"></param>
public static void SelectSort(List<int> list)
{
for (int i = 0; i < list.Count-1; i++)
{
int minIndex = i;
int temp = list[i];
for (int j = i+1; j < list.Count; j++)
{
if (temp > list[j])
{
minIndex = j;
temp = list[j];
}
}
if (minIndex != i)
Swap(list, i, minIndex);
}
}
/// <summary>
/// 冒泡排序
/// 原理:从头开始,每一个元素和它的下一个元素比较,如果它大,就将它与比较的元素交换,否则不动。
/// 这意味着,大的元素总是在向后慢慢移动直到遇到比它更大的元素。所以每一轮交换完成都能将最大值
/// 冒到最后。
/// </summary>
/// <param name="list"></param>
public static void BubbleSort(List<int > list)
{
for (int i = list.Count-1; i >0; i--)
{
for (int j = 0; j <i; j++)
{
if (list[j] > list[j + 1])
Swap(list, j, j + 1);
}
}
}
/// <summary>
/// 改良版冒泡排序,也有点选择排序得影子
/// </summary>
/// <param name="nums"></param>
private void Sort(List<int> nums)
{
int temp;
for (int i = 0; i < nums.Count-1; i++)
{
temp = nums[i];
for (int j = i+1; j < nums.Count; j++)
{
if (temp > nums[j])
{
nums[i] = nums[j];
nums[j] = temp;
temp = nums[i];
}
}
}
}
/// <summary>
/// 插入排序
/// 原理:通过构建有序数列,将未排序的数从后向前比较,找到合适位置并插入。
/// </summary>
/// <param name="list"></param>
public static void InsertSort(List<int> list)
{
int temp;
//int curIndex;
for (int i = 1; i < list.Count; i++)
{
temp = list[i];
//curIndex = i;
for (int j = i - 1; j >= 0; j--)
{
if (temp > list[j])//大于j就在j索引后面,退出当前排序
{
list[j + 1] = temp;
break;
}
else//反之就在前面,记住索引继续排序
{
//Swap(list, curIndex, j);
//curIndex = j;
list[j + 1] = list[j];
if(j==0)
{
list[0] = temp;
break;
}
}
}
}
}
/// <summary>
/// 快速排序
/// 原理:从数列中挑选一个数作为“哨兵”,使比它小的放在它的左侧,比它大的放在它的右侧。将要排序是数列递归地分割到
/// 最小数列,每次都让分割出的数列符合“哨兵”的规则,自然就将数列变得有序。
/// </summary>
/// <param name="list"></param>
public static void QuickSort(List<int> list)
{
QuickSort(list, 0, list.Count - 1);
}
private static void QuickSort(List<int> list,int left,int right)
{
if (left >= right)
return;
int temp = list[left];
int i = left + 1, j = right;
while (true)
{
while (list[j] > temp) j--;
while (list[i] < temp && i < j) i++;
if (i >= j)
break;
Swap(list, i, j);
i++;j--;
}
if (j != left)
Swap(list, left, j);
QuickSort(list, j + 1, right);
QuickSort(list, left, j - 1);
}
private static void QuickSort2(List<int> list, int left, int right)
{
if (left >= right) return;
int temp = list[(left + right) / 2];
int i = left - 1, j = right + 1;
while (true)
{
while (list[++i] < temp) ;
while (list[--j] > temp) ;
if (i >= j) break;
Swap(list, i, j);
}
QuickSort2(list, left, i - 1);
QuickSort2(list, j + 1, right);
}
/// <summary>
/// 归并排序(合并排序)
/// 原理:将两个有序的数列,通过比较,合并为一个有序数列。
/// </summary>
/// <param name="list"></param>
public static List<int> MergeSort(List<int > list)
{
return MergeSort(list, 0, list.Count - 1);
//return MergeSortOnlyList(list, 0, list.Count - 1);
}
private static List<int > MergeSort(List<int> list,int left,int right)
{
if (left == right)
return new List<int> { list[left] };
List<int> mergeData = new List<int>();
int center = (left + right) / 2;
List<int> leftList = MergeSort(list, left, center);
List<int> rightList = MergeSort(list, center + 1, right);
int i = 0, j = 0;
while (true)
{
if(leftList[i]<rightList[j])
{
mergeData.Add(leftList[i++]);
if(i==leftList.Count)
{
mergeData.AddRange(rightList.GetRange(j, rightList.Count - j));
break;
}
}
else
{
mergeData.Add(rightList[j++]);
if(j==rightList.Count)
{
mergeData.AddRange(leftList.GetRange(i, leftList.Count - i));
break;
}
}
}
return mergeData;
}
public static List<int> MergeSortOnlyList(List<int> data, int low, int high)
{
if (low == high)
return new List<int> { data[low] };
List<int> mergeData = new List<int>();
int mid = (low + high) / 2;
List<int> leftData = MergeSortOnlyList(data, low, mid);
List<int> rightData = MergeSortOnlyList(data, mid + 1, high);
int i = 0, j = 0;
while (true)
{
if (leftData[i] < rightData[j])
{
mergeData.Add(leftData[i]);
if (++i == leftData.Count)
{
mergeData.AddRange(rightData.GetRange(j, rightData.Count - j));
break;
}
}
else
{
mergeData.Add(rightData[j]);
if (++j == rightData.Count)
{
mergeData.AddRange(leftData.GetRange(i, leftData.Count - i));
break;
}
}
}
return mergeData;
}
/// <summary>
/// 堆排序(都是从小到大)
/// 原理:将数列构建为最大堆数列(即父节点总是最大值),将最大值(即根节点)交换到数列末尾。这样要排序的数列数总和减少,
/// 同时根节点不再是最大值,调整最大堆数列。如此重复,最后得到有序数列
/// </summary>
/// <param name="list"></param>
public static void HeapSort(List<int> list)
{
BuildMaxHeap(list);//第一轮排序完之后,父节点都大于子节点
int j = list.Count;
for (int i = 0; i < j; )
{
//将每轮的根节点的(剩余数中最大)放在最后从后往前排列
Swap(list, i, --j);
if (j - 2 < 0)//只剩下1个数 j代表余下要排列的数的个数
break;
int k = 0;
while(true)
{
if (k > (j - 2) / 2)//超出最后一个父节点的位置
break;
else
{
int temp = k;
k = ReSortMaxBranch(list, k, 2 * k + 1, 2 * k + 2, j - 1);
if (temp == k)
break;
}
}
}
}
private static void BuildMaxHeap(List<int> list)
{
for (int i = list.Count / 2 - 1; i >= 0; i--)
{
int temp = i;
temp = ReSortMaxBranch(list, i, 2 * i + 1, 2 * i + 2, list.Count - 1);
if (temp != i)//返回索引不是父节点
{
int k = i;
while (k != temp && temp <= list.Count / 2 - 1)//计算一次后如果父节点比子节点大&&如果没有子节点
{
k = temp;
temp = ReSortMaxBranch(list, temp, 2 * temp + 1, 2 * temp + 2, list.Count - 1);
}
}
}
}
private static int ReSortMaxBranch(List<int> list,int maxIndex,int left,int right,int lastIndex)
{
int temp;
if (right > lastIndex)//说明父节点只有一个子节点
temp = left;
else
{
if (list[left] > list[right])//判断两个子节点哪个大
temp = left;
else
temp = right;
}
if (list[maxIndex] < list[temp])//如果父节点比子节点小,交换索引,返回子节点索引
Swap(list, maxIndex, temp);
else
temp = maxIndex;//否则返回父节点索引
return temp;
}
/// <summary>
/// 希尔排序
/// 原理:通过奇妙的步长,插入排序间隔步长的元素,随后逐渐缩短步长至1,实现数列的插入排序。
/// (不太理解他这怎么缩进的)
/// </summary>
/// <param name="list"></param>
public static void ShellSort(List<int> list)
{
int temp;
for (int gap = list.Count; gap > 0; gap /= 2)
{
for (int i = gap; i < list.Count; i += gap)//i+=gap改为i++
{
temp = list[i];
for (int j = i - gap; j >= 0; j -= gap)
{
if (list[j] > temp)
{
list[j + gap] = list[j];
if (j == 0)
{
list[j] = temp;
break;
}
}
else
{
list[j + gap] = temp;
break;
}
}
}
}
}
/// <summary>
/// 基数排序(暂时不理解,这个方法目前只支持正数)
/// 原理:将整数按位数切割成不同的数字,然后按每个位数分别比较
/// </summary>
/// <param name="list"></param>
public static List<int> RadixSort(List<int> list)
{
int max = list[0];
for (int i = 1; i < list.Count; i++)
{
if (list[i] > max)
max = list[i];
}
int count = 1;//看多少位数
while(max/10!=0)
{
count++;
max /= 10;
}
for (int i = 0; i < count; i++)
{
int[] indexCounter = new int[10];
List<int> tempList = new List<int>();
tempList.AddRange(list);
for (int j = 0; j < list.Count; j++)
{
int number = (list[j] % Convert.ToInt32(Math.Pow(10, i + 1))) / Convert.ToInt32(Math.Pow(10, i));//得出i+1位上的数
indexCounter[number]++;
}
int[] indexBegin = new int[10];
for (int k = 1; k < 10; k++)
{
indexBegin[k] = indexBegin[k - 1] + indexCounter[k - 1];
}
for (int k = 0; k < list.Count; k++)
{
int number = (list[k] % Convert.ToInt32(Math.Pow(10, i + 1))) / Convert.ToInt32(Math.Pow(10, i));
tempList[indexBegin[number]++] = list[k];
}
list = tempList;
}
return list;
}
#region 通用代码
/// <summary>
/// 交换位置
/// </summary>
/// <param name="list">集合</param>
/// <param name="current">当前索引</param>
/// <param name="swap">交换索引</param>
public static void Swap(List<int> list,int current,int swap)
{
int temp = list[current];
list[current] = list[swap];
list[swap] = temp;
}
#endregion
}
}
C#实现8种基础排序算法
简介
排序算法是我们编程中遇到的最多的算法。目前主流的算法有8种。
平均时间复杂度从高到低依次是:
冒泡排序(o(n2)),选择排序(o(n2)),插入排序(o(n2)),堆排序(o(nlogn)),
归并排序(o(nlogn)),快速排序(o(nlogn)), 希尔排序(o(n1.25)),基数排序(o(n))
冒泡排序
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎