各类排序算法的实现C#版
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Schema;
namespace Sort
{
class Program
{
//内排序
//一、插入排序
//1.直接插入排序法
/*直接插入排序(straight insertion sort)的作法是:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
*直接插入排序属于稳定的排序,时间复杂性为o(n^2),空间复杂度为O(1)。
* 插入排序类似玩牌时整理手中纸牌的过程。
*/
static void InsertSort(int[] dataArray)
{
for (int i = 1; i < dataArray.Length; i++)//外层循环用来确定待比较的数值
{
int iValue = dataArray[i]; //保存索引1的位置,不然会被覆盖
bool isRightInsert = false;
for (int j = i - 1; j >= 0; j--)//内循环确定最终的位置
{
if (dataArray[j] > iValue)
{
dataArray[j + 1] = dataArray[j];
}
else
{
dataArray[j + 1] = iValue;//如果0索引位置比1索引位置小,就不用移动,
isRightInsert = true;
break;
}
}
//标签在循环后面,先循环确定n-1个数的顺序,最后与dataArray[0]进行判断0索引位置是否已经前移,是的话iValue为最小元素被插入到0号索引位置
if (isRightInsert == false)
{
dataArray[0] = iValue;
}
}
}
//直接插入排序法(优化)
//思考c#面向对象的编程语言的优化问题,标签是否能省去。
//c++版数据结构中
static void InsertSortPro(int[] dataArray)//n表示直到第n个记录插入完毕
{
int iValue, j;
for (int i = 1; i < dataArray.Length; i++)//直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的.
{
iValue = dataArray[i];
j = i - 1;
while (j >= 0 && dataArray[j] > iValue)//只要i前一个数比i大,进入内循环
//for (int j = i - 1; dataArray[0] < dataArray[j]; j++)
{
dataArray[j + 1] = dataArray[j];//第一轮是将dataArray[1]的位置覆盖了,并将标记移向后面,插入的时候位置就是满足大的在后,小的在前的顺序
j--;
}
dataArray[j + 1] = iValue;//第一轮内循环这里j+1=0;如果没有发生交换,j+1=1;
}
}
//2.折半插入排序
/* 折半插入排序(binary insertion sort)是对插入排序算法的一种改进,由于排序算法过程中,就是不断的依次将元素插入前面已排好序的序列中。由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度。
*折半插入排序属于稳定的排序,时间复杂性为o(n^2),空间复杂度为O(1)。
* 只是优化了比较的次数
*/
static void BinaryDirSort(int[] dataArray)
{
for (int i = 1; i < dataArray.Length; i++)
{
int left = 0;
int right = i - 1;//定义两个游标,用来确定一个插入的区域
int mid = 0;//插入的位置
int iValue = dataArray[i];
while (left <= right)
{
mid = (left + right) / 2;
if (iValue < dataArray[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
for (int j = i; j > mid; j--)//由于前面的数据已经是有序的了。
{
dataArray[j] = dataArray[j - 1];
}
dataArray[left] = iValue;// 将此位置之后所有元素后移一位,并将新元素插入a[high + 1]。//此时的left=right+1
}
}
//3.希尔排序(不稳定)
/* 希尔排序(Shell Sort)又叫做缩小增量排序(diminishing increment sort)
* Donald Shell发明的算法,对指定间距的元素排序,排好后缩小间距继续直到间距为1并不在变化
*/
static void ShellSort(int[] dataArray)
{
int gap = dataArray.Length / 2; //取长度的一半
bool HasChange = true;
while (gap > 1 || HasChange)
{
HasChange = false;
for (int i = 0; i + gap < dataArray.Length; i++)
{
if (dataArray[i] > dataArray[i + gap])
{
int temp = dataArray[i];
dataArray[i] = dataArray[i + gap];
dataArray[i + gap] = temp;//交换并设置下一轮循环
HasChange = true;
}//当条件不满足的时候证明该间距内没有变化(有序)了
if (gap > 1)
{
gap /= 2;
}
}
}
}
//二、选择排序
//1.直接选择排序(不稳定)
/*选择拍序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个 元素不用选择了
*/
static void SelectSort(int[] dataArray)
{
for (int i = 0; i < dataArray.Length; i++)
{
int min = dataArray[i];
int minindex = i;
for (int j = i + 1; j < dataArray.Length; j++)
{
if (dataArray[j] < min)
{
min = dataArray[j];
minindex = j;
}
}
if (i != minindex)//判断是否需要进行交换
{
int temp = dataArray[i];
dataArray[i] = dataArray[minindex];
dataArray[minindex] = temp;
}
}
}
//选择排序加强版
//(改变了遍历顺序优化了代码量)找出最小的然后和第一个数交换,再从第2到n-1中找出最小的和第二个数交换
static void SelectSortPro(int[] dataArray)
{
for (int i = dataArray.Length - 1; i > 0; i--)
{
for (int j = 0; j < i; j++)
{
if (dataArray[j] > dataArray[i])
{
int temp = dataArray[i];
dataArray[i] = dataArray[j];
dataArray[j] = temp;
}
}
}
}
//2.堆排序
//是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构(通常堆是通过一维数组来实现的),并同时满足堆的性质:即子结点的键值总是小于(或者大于)它的父节点
private static int n;//设置一个全局的n表示栈的大小
static void SetStack(int[] dataArray, int i)
{
int left = i * 2 + 1;//最大堆的左子树
int right = i * 2 + 2;//最大堆的右子树
int max; // 保存当前栈顶元素(最大值)
if (left < n && dataArray[left] > dataArray[i])
{
max = left;
}
else
{
max = i;
}
if (right < n && dataArray[right] > dataArray[max])
{
max = right;
}
if (max != i)//如果发生了上面的交换
{
int temp = dataArray[i];
dataArray[i] = dataArray[max];
dataArray[max] = temp;//交换
SetStack(dataArray, max);//递归来进行堆调整
}
}
static void StackSort(int[] dataArray)
{
n = dataArray.Length;//设置堆的大小
for (int i = n / 2 - 1; i >= 0; i--)//对不是叶子结点的进行下面的堆设置
{
SetStack(dataArray, i);
}
for (int i = dataArray.Length - 1; i >= 1; i--)
{
int temp = dataArray[0];
dataArray[0] = dataArray[i];
dataArray[i] = temp;//当前最大值(栈顶)与最后一个的元素互换(不稳定)
n--;//去掉最后一个元素(已经排好)
SetStack(dataArray, 0);//调用调整函数重新从栈顶开始调整
}
}
//三、交换排序
//1.简单的冒泡排序,判断过程中是否有交换发生,如果没有交换,说明已经完成排序了
static void PopSort(int[] dataArray)
{
bool isSort = true;//加个判断是否已经排好
for (int i = 0; i < dataArray.Length - 1 && isSort; i++)
{
isSort = false;
for (int j = 0; j < dataArray.Length - i - 1; j++)//j从i+1的位置开始,优化了不必要的遍历
{
if (dataArray[j] > dataArray[j + 1])
{
int temp = dataArray[j];
dataArray[j] = dataArray[j + 1];
dataArray[j + 1] = temp;
isSort = true;
}
}
}
}
//冒泡逆排(顺序从后往前)
static void ReversePopSort(int[] dataArray)
{
for (int i = dataArray.Length - 1; i > 0; i--)//0到n-1
{
for (int j = 0; j < i; j++)
{
if (dataArray[j] > dataArray[j + 1])
{
int temp = dataArray[j];
dataArray[j] = dataArray[j + 1];
dataArray[j + 1] = temp;
}
}
}
}
//鸡尾酒定向冒泡排序(从前到后再从后到前冒泡)
static void CocktailSort(int[] dataArray, int left, int right)
{
while (left < right)
{
for (int i = left; i < right; i++)
{
if (dataArray[i] > dataArray[i + 1])
{
int temp = dataArray[i];
dataArray[i] = dataArray[i + 1];
dataArray[i + 1] = temp;
}
right--;
for (int j = right; j > left; j--)
{
if (dataArray[j - 1] > dataArray[j])
{
int temp = dataArray[j];
dataArray[j] = dataArray[j - 1];
dataArray[j - 1] = temp;
}
left++;
}
}
}
}
//2.快速排序(不稳定)
//用到了分治的策略方法
//思想
//1,数组中娶一个基准数
//将比这个数大的放到右边,小于等于的放到左边
//再分而治之,对排除该数两边的数组做1,2步骤,直到两边只剩下1个数
/// <summary>
///
///对数组dataArray中索引从left到right的数做排序
/// </summary>
/// <param name="dataArray"></param>
/// <param name="left">左标签</param>
/// <param name="right">右标签</param>
static void FastSort(int[] dataArray, int left, int right)
{
if (left < right)
{
int basis = dataArray[left];//选择第一个数作为基准数,把比他小或等于的放在左边,比他大的放在右边
int i = left;
int j = right;
//从后往前
while (true && i < j)//当i==j时,说明我们找到了一个中间位置,就是基准数basis存放的位置
{
while (true && i < j)
{
if (dataArray[j] <= basis)//找到比basis小于或等于的数放在左边
{
dataArray[i] = dataArray[j];
break;//找到后就可以跳出循环了
}
else
{
j--;//向左移动到下一个
}
}
//从前往后找比basis大的数,放在j位置的坑里
while (true && i < j)
{
if (dataArray[i] > basis)
{
dataArray[j] = dataArray[i];
break;
}
else
{
i++;
}
}
}
dataArray[i] = basis;//i==j等于中间位置
//分成了left-i-right
FastSort(dataArray, left, i - 1);
FastSort(dataArray, i + 1, right);//分成两部分分别进行排序
}
}
//四、归并排序
//递归实现的归并排序是算法设计中分治策略的典型应用,我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题
//基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序
//先递(归)的分解数列,再合(并)数列就完成了归并排序。
//稳定,时间复杂度O(nlogn)
//分为递归实现(RecursionMergeSort)与非递归(迭代)(IterationMergeSort)实现
//1.二路归并(递归)
public static int[] dataArrayB;//归并过程可能破坏有序序列,所以将结果放入dataArrayB中
static void RecursionMergeSort(int[] dataArrayA, int left, int right)
{
if (left == right)//如果左右相等了,说明数组长度为1,直接return,一个数比个球(╯‵□′)╯︵┻━┻
{
return;
}
else
{
dataArrayB = new int[dataArrayA.Length];//new一个和dataArrayA一样大小的数组存放序列
int mid = (right + left) / 2;//两个序列的中间值
RecursionMergeSort(dataArrayA, left, mid);
RecursionMergeSort(dataArrayA, mid + 1, right);//递(归)调用RecursionMergeSort,将序列细分
//下面是具体一次的归并算法
//把若干相邻长度相同的有序序列和最后一个可能小于该长度的序列两两归并,一一保存到数组dataArrayB中
int i = left;
int j = mid + 1;
int k = left;//i,k初始指向第一个序列的第一个值,j指向第二个序列的第一个值
//合(并)序列
while (i <= mid && j <= right)//当同时满足时,根据左右序列中的值的大小确定合并的顺序
{
if (dataArrayA[i] < dataArrayA[j])
dataArrayB[k++] = dataArrayA[i++];
else
dataArrayB[k++] = dataArrayA[j++];
}
while (i <= mid)
dataArrayB[k++] = dataArrayA[i++];
while (j <= right)
dataArrayB[k++] = dataArrayA[j++];
for (int s = left; s <= right; s++)//将数组dataArrayB中的值依次重新赋给dataArrayA
dataArrayA[s] = dataArrayB[s];
}
}
//2.二路归并(迭代)
public static int[] dataArrayC;//归并过程可能破坏有序序列,所以将结果放入dataArrayC中
static void Merge(int[] dataArray, int left, int mid, int right)//一次归并
{
int i = left;
int j = mid + 1;
int cleft = left;
dataArrayC = new int[dataArray.Length];
//合(并)序列
while (i <= mid && j <= right)//当同时满足时,根据左右序列中的值的大小确定合并的顺序
{
if (dataArray[i] < dataArray[j])
dataArrayC[cleft++] = dataArray[i++];
else
dataArrayC[cleft++] = dataArray[j++];
}
if (i <= mid)
{
while (i <= mid)
dataArrayC[cleft++] = dataArray[i++];
}
else
{
while (j <= right)
dataArrayC[cleft++] = dataArray[j++];
}
for (int s = left; s <= right; s++)//将数组dataArrayB中的值依次重新赋给dataArrayA
dataArray[s] = dataArrayC[s];
}
static void Merge_Pass(int[] dataArray, int h)//有个pass判断该怎么(归)
{
int i = 0;//从零存放待排序的序列
while (i <= dataArray.Length + 1 - 2 * h)//记录至少还有两个h长度的子序列
{
Merge(dataArray, i, i + h - 1, i + 2 * h - 1);
i += 2 * h;//加上2个h长度,完成一次归并
}
if (i < dataArray.Length - h)//表明存在有两个相邻有序序列的总长度小于2h(其中一个长度小于h)
{
Merge(dataArray, i, i + h - 1, dataArray.Length - 1);
}
else
{
for (int k = i; k <= dataArray.Length - 1; k++)//只剩下最后一个子序列时,直接放在dataArrayC相应的位置,完成一次归并
{
dataArrayC[k] = dataArray[k];
}
}
}
static void IteratorMergeSort(int[] dataArray)
{
int h = 1;//初始子序列长度
while (h < dataArray.Length)//长度控制(并)过程的结束
{
Merge_Pass(dataArray, h);
h += h;
Merge_Pass(dataArray, h);
h += h;
}
}
//3.自然归并排序
//:对二路并归的一种改进,只将有序的自序列进行归并,但是如果是乱序的话,也是要分成长度为1的子序列,这里相当于把序列中已经是排列好的有序列当成子序列进行归并(natural merge sort)
public static int[] dataArrayD;//归并过程可能破坏有序序列,所以将结果放入dataArrayD中
static void NaturalSort(int[] dataArray)
{
dataArrayD = new int[dataArray.Length];
int k = 0;
for (int i = 0; i < dataArray.Length - 1; i++)
{
if (dataArray[i] > dataArray[i + 1])
{
dataArrayD[k++] = i;//dataArray里存的分割好的序列的首元素
}
}
dataArrayD[k++] = dataArray.Length - 1;//遍历完成后,将下一个位置存放dataArray的长度,其实主要是k++,保证p<k不会漏掉最后一次的归并
int left, mid = 0, right;//记录两子序列的左中右位置
left = 0;
int p = 0;//记录子序列的个数(dataArayD的索引)
if (p < k)//p<k是判断是否还有子序列(归并完成)
{
mid = dataArrayD[p++];//中间值是子序列首元素位置
}
while (p < k)
{
right = dataArrayD[p++];
Merge(dataArray, left, mid, right);//进行一次归并
mid = right;//把归并后的子序列的末尾当成下一次归并的中间长度
}
}
//五、分配排序
//箱排序(桶式排序)
//基本思想是:将待排序的序列分配到不同的桶里,然后把桶里的记录依次收集到一起。
//箱排序一般用来处理一定范围内的整数的排序(年龄,分数)
/*
书上写的不全,c++真坑
struct DataNode//定义静态链表存储待序列排序
{
public int key;
public int next;//下一个key的值
}
struct BucketQueue//定义静态队列存储桶
{
public int front, rear;
}
static void BucketSort(int []dataArray)
{
DataNode[] node=new DataNode[dataArray.Length];
int max=dataArray[0]; //保存dataArray最大值
for (int i = 0; i < dataArray.Length; i++)//初始化静态链表
{
node[i].next = i + 1;
node[i].key = dataArray[i];
if (dataArray[i]>max)
{
max = dataArray[i];
}
}
node[dataArray.Length - 1].next= -1;
int first = 0; //设置头尾标记
BucketQueue[] bucket = new BucketQueue[max];
for (int i = 0; i < max; i++)//初始化0-max个静态队列的队头队尾指针
{
bucket[i].front = bucket[i].rear = -1;
}
//分配到箱子里
int x = first;
while (node[x].next != -1)//依次分配每一个记录
{
int temp = node[x].key;
Console.WriteLine(temp);
if (bucket[temp].front==-1)
{
bucket[temp].front = x;//处理BucketQueue[]中为空的情况
}
else
{
node[bucket[temp].rear].next = x;//在静态链表node里通过改变next来实现插入BucketQueue队尾
}
bucket[temp].rear = x;//将队尾元素指给first
x= node[x].next;//first头标记后移来处理下一个记录
}
//将队列中非空元素收尾相连
int count= 0;
first = 0;
// Console.Write(bucket[count].front);
while (bucket[count].front==-1)//找到一个非空元素将count加1
count++;
first = bucket[count].front;
int last = bucket[count].rear;
while (count<max-1)
{
count++;
if (bucket[count].front != -1) //BucketQueue中第count个非空元素
{
node[last].next = bucket[count].front;//将bucket[count]的头与前一个node元素的尾相连
last = bucket[count].rear;//last存放当前收集的最后一个记录
}
}
node[last].next = -1;//最后的node[last]的下一个置为-1
for (int i = 0; i < dataArray.Length; i++)//将排好的有序的DataNode数据赋给dataArray数组
{
Console.WriteLine(node[i].next) ;
}
for (int i = 0; i <max; i++)
{
Console.WriteLine(bucket[i].front) ;
Console.WriteLine(bucket[i].rear) ;
}
} */
//桶排序(偷懒版)用自带的List来序列化获得的参数
static void BucketSort(int[] dataArray)
{
int max = dataArray[0]; //保存dataArray最大值
for (int i = 0; i < dataArray.Length; i++)
{
if (dataArray[i] > max)
{
max = dataArray[i];
}
}
int[] dataArrayE=new int[max+1];//new一个dataArrayE作为箱,大小是0-max+1
for (int i = 0; i <dataArray.Length; i++)
{
int k = dataArray[i];
dataArrayE[k]++; //这里将dataArray对应在dataArrayE箱里的值加1
}
List<int> data=new List<int>();
for (int i = 0; i<dataArrayE.Length; i++)
{
int num = dataArrayE[i];//num保存了dataArrayE里的值,对应dataArray里的值为1,其余为0
for (int j = 1; j <= num; j++)
{
data.Add(i);//num为1时,就是存了值的箱,直接把它加入List里,
}
}
for (int i = 0; i <dataArray.Length; i++)
{
dataArray[i]=data[i];//把List里的值拿出来赋给原数组
}
}
// 基数排序(按位数排序)
//按照低位先排序,然后收集;再按照高位排序,然后再收集;
//依次类推,直到最高位.如果在某一位的数字相同,那么排序结果要根据上一轮的数组确定。
static void RadixSort(int[] dataArray)
{
int d = 0; //存储序列最大的位数
for (int i = 0; i <dataArray.Length; i++)
{
int b = 1; //临时变量表示位数
int r = dataArray[i];
while (r / 10 > 0) //int不存小数位
{
b++;
r /= 10;
}
if (d < b)
d = b;
}
int[] temp = new int[dataArray.Length];//保存排序的序列
int[] count = new int[10]; //记录当前位数0-9数字的个数以排序
int radix = 1; //进位操作*=10
for (int i = 0; i <=d; i++)
{
for (int j = 0; j < 10; j++)
{
count[j] = 0; //初始化
}
for (int j = 0; j < dataArray.Length; j++)
{
int k = (dataArray[j] / radix) % 10;//k取得指定位数的数值
count[k]++; //指定的位数的数值的个数加1
}
for (int j = 1; j < 10; j++)
{
count[j] += count[j - 1];//加上前一位的个数确定在总长度的位置关系
}
for (int j = dataArray.Length-1; j >=0; j--)
{
int k = (dataArray[j] / radix) % 10;//k取得指定位数的数值
count[k]--; //每找到一个位数的数值相同的将count中的位置再左移一位
temp[count[k]] = dataArray[j];//根据count中保存的位置信息,保存到指定的位置
}
for (int j = 0; j < dataArray.Length; j++)
{
dataArray[j] = temp[j];//赋给dataArray数组进行下一位的排序
}
radix *= 10;//下一位的除值乘十
}
}
//计数排序,按名次排序
//先将序列的大小关系按计数法排个名次
static void CountingSrot(int[] dataArray)
{
int [] RankArray=new int[dataArray.Length]; //存放序列名次
int[] temp=new int[dataArray.Length]; //存放临时排序序列
for (int i = 0; i < dataArray.Length; i++)
{
RankArray [i]= 0; //初始化名次数组
}
for (int i = 0; i < dataArray.Length; i++)
{
for (int j = 0; j < i; j++)
{
if (dataArray[j] <= dataArray[i]) //前面小于等于的数
{
RankArray[i]++; //dataArray[i]的名次往后一位
}
else
{
RankArray[j]++;
}
}
}
for (int j = 0; j < dataArray.Length; j++)
{
temp[RankArray[j]] = dataArray[j];//按排好的名次将dataArray的值依次赋给temp
}
for (int k = 0; k < dataArray.Length; k++)
{
dataArray[k] = temp[k];//将排好的序列重新赋给dataArray数组
}
}
static void Main(string[] args)//参考网站,文章
{
int[] s = new[] { 42, 20, 17, 27, 13, 8, 17, 48 };
// SelectSort(s);
//InsertSortPro(s);
//BinaryDirSort(s);
// ShellSort(s);
// StackSort(s);
//ReversePopSort(s);
// RecursionMergeSort(s,0,s.Length-1);
//IteratorMergeSort(s);
// NaturalSort(s);
//BucketSort(s);
// RadixSort(s);
//CountingSrot(s);
// FastSort(s,0,s.Length-1);
foreach (var temp in s)
{
Console.WriteLine(temp);
}
Console.WriteLine();
Console.Read();
}
}
}
参考文章:http://www.cnblogs.com/xkfz007/archive/2012/07/01/2572017.html
参考视频:siki
参考网站:http://www.cs.usfca.edu/~galles/visualization/Algorithms.html
各类排序算法的实现C#版的更多相关文章
- Python学习(三) 八大排序算法的实现(下)
本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...
- 排序算法的实现之Javascript(常用)
排序算法的实现之Javascript 话不多说,直接代码. 1.冒泡排序 1.依次比较相邻的两个数,如果前一个比后一个大,则交换两者的位置,否则位置不变 2.按照第一步的方法重复操作前length-1 ...
- 排序算法的实现(归并,快排,堆排,希尔排序 O(N*log(N)))
今天跟着左老师的视频,理解了四种复杂度为 O(N*log(N))的排序算法,以前也理解过过程,今天根据实际的代码,感觉基本的算法还是很简单的,只是自己写的时候可能一些边界条件,循环控制条件把握不好. ...
- python排序算法的实现-插入
1.算法: 设有一组关键字{ K 1 , K 2 ,…, K n }:排序开始就认为 K 1 是一个有序序列:让 K 2 插入上述表长为 1 的有序序列,使之成为一个表长为 2 的有序序列:然后让 K ...
- 排序算法的实现(C/C++实现)
存档: #include <iostream> #include <stdlib.h> #include <sort.h> #define maxsize 20 u ...
- 一起学Hadoop——二次排序算法的实现
二次排序,从字面上可以理解为在对key排序的基础上对key所对应的值value排序,也叫辅助排序.一般情况下,MapReduce框架只对key排序,而不对key所对应的值排序,因此value的排序经常 ...
- 基于python的几种排序算法的实现
#!usr/bin/python3 # -*- coding: utf-8 -*- # @Time : 2019/3/28 10:26 # @Author : Yosef-夜雨声烦 # @Email ...
- Python之基本排序算法的实现
import cProfile import random class SortAlgorithm: def __init__(self,unsortedlist=[]): self.unsorted ...
- 排序算法的实现(冒泡,选择,插入 O(N*N)--理解方法实现
以前也看过很多排序算法的原理,每次都想自己实现一下,一直都再拖,现在着牛课网学习算法课程,希望自己能够坚持练习. //对于一个int数组,请编写一个选择冒泡算法,对数组元素排序. //给定一个int数 ...
随机推荐
- Unable to determine the device handle for GPU 0000:01:00.0: GPU is lost.问题排坑
在运行maskrcnn时,会碰到训练不动的问题,就卡在这儿 UserWarning: Converting sparse IndexedSlices to a dense Tensor of unkn ...
- Spring重要知识点整理
一.IOC(Inversion of Control):控制反转 (1)Spring Core最核心部分 (2)需要先了解依赖注入(Denpendency Injection)/把底层类作为参数传递给 ...
- 设置tomcat支持软连接
一般开发时不会在tomcat安装目录/data/tomcat/webapps/ROOT 下去,上传部署:而是建立软连接,在tomcat安装目录之外操作,比如执行git pull拉取项目,而tomcat ...
- sed 命令简介
sed 默认把文件内容全部显示出来(擅长取行 替换) 参数如下: - n 取消默认输出 一般与P一起使用 查看内容‘10,20p’ 显示10-20 行的内容 - i 修改文件内容 - i.bak ...
- 实训任务04 MapReduce编程入门
实训任务04 MapReduce编程入门 1.实训1:画图mapReduce处理过程 使用有短句“A friend in need is a friend in deed”,画出使用MapReduce ...
- 零基础学习JavaSE(一)
一.开发环境安装配置 1.1 安装jdk jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载后安 ...
- alibaba/druid 下的 密码加密
使用ConfigFilter cliangch edited this page on 3 Feb · 12 revisions ConfigFilter的作用包括: 从配置文件中读取配置 从远程ht ...
- Charles篡改请求,在手机上抓包,以及弱网设置
篡改请求 可以测试各种异常 原理:clint->server正常是客户端发送请求到服务端,charles相当于一个拦截器,拦住客户端的请求,并进行修改,修改后再发送到server端 Server ...
- 安装SSD
前面两篇文章讲了用SSD检测框架训练自己的数据集,这篇补充一下SSD的安装.github链接:https://github.com/weiliu89/caffe/tree/ssdSSD是16年ECCV ...
- Linux 下使用umount强行卸载设备
卸载NFS,结果出现无法卸载的情况 [root@localhost /]# umount /udisk/ umount: /udisk: device is busy umount: /udisk: ...