快速排序
/// <summary>
/// 快速排序
/// 快速排序的原理是把数组中的一个数看做中间数,从右到左找一个比中间数大的数字,将该数字放在最左,然后缩小右的范围为右-1
/// 然后从左到右找一个比中间数大的数字,放在最右,然后缩小左的范围为左+1,直到左右范围相等
/// 此时中间数左边的数字都比中间数小,右边的数字都比中间数大,我们在本次方法中确定了一个中间数的位置
/// 中间数将数组划分成了 (0,中间数-1) 中间数 (中间数+1,lenth-1)3个部分,对新划分的两个区域递归调用快速排序的方法
/// 所有中间数都确定的时候 数组就完成了排序
/// </summary>
/// <param name="arrays">需要排序的数组</param>
/// <param name="startIndex">本次排序范围的起始</param>
/// <param name="endIndex">本次排序范围的终止</param>
void quickSort(int[] arrays,int startIndex,int endIndex) {
if (arrays==null || startIndex>=endIndex)
{
return;
}
//baseInt是本次假定的中间数
//中间数当然是位置越趋于中间,效率越高。本次假设不知道数组的规律,默认取第一个数字看做中间数
//如果数组有规律的话 可以想办法让中间数更接近中间 达到一些优化效果
int baseInt = arrays[startIndex];
int tempLeft = startIndex;//数组左下标
int tempRight = endIndex;//数组右下标
while (tempLeft < tempRight)
{
while (tempLeft < tempRight && arrays[tempRight] >= baseInt)
{
tempRight--;
}
arrays[tempLeft] = arrays[tempRight];
while (tempLeft < tempRight && arrays[tempLeft] <= baseInt)
{
tempLeft++;
}
arrays[tempRight] = arrays[tempLeft];
}
arrays[tempLeft] = baseInt;
quickSort(arrays, startIndex, tempLeft - 1);
quickSort(arrays, tempLeft + 1, endIndex);
}
插入排序
/// <summary>
/// 插入排序的原理是 将一个乱序数组 依次插入到有序的数组中
/// 默认有序数组是array第一项 将array第二项起依次找到该元素在有序数组中的位置 并插入
/// </summary>
/// <param name="array"></param>
void InsertSort(int[] array) {
//因为第一个数直接插入不需要计算 所以i从1开始
for (int i = 1; i < array.Length; i++)
{
//移动过程会破坏数组顺序 先保存当前要插入的数字
int temp = array[i];
//要进行从后向前i-1次循环
int j = i - 1;
while (j >= 0 && array[j] > temp)
{
//如果当前数字比当前要插入的数字大 向右移动
array[j + 1] = array[j];
j--;
}
//下一项就是本次该插入的位置
array[j + 1] = temp;
}
}
简化版
把当前要插入的数字,用交换的方式代替原来移动的方式
代码简洁很多
/// <summary>
/// 插入排序
/// </summary>
/// <param name="array"></param>
void InsertSort2(int[] array) {
for (int i = 1; i < array.Length; i++)
{
for (int j = i-1; j>=0 && array[j]>array[j+1]; j--)
{
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
选择排序
/// <summary>
/// 选择排序 遍历数组寻找最小值
/// 将最小值与最前项交换
/// 缩小范围 重复上一步
/// </summary>
/// <param name="array"></param>
void SelectSort(int[] array) {
//依次将最小数放置数组 最后一个数字一定是最大的 所以减少一次循环
for (int i = 0; i < array.Length-1; i++)
{
int minIndex=i;//最小数的小标 默认为本次循环的起始点
//从i开始找最小数 前面已经排好了
for (int j = i; j < array.Length; j++)
{
if (array[j]<array[minIndex])
{
minIndex = j;
}
}
//如果最小数不在当前位置 则交换最小数到当前位置
if (i!=minIndex)
{
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
}
冒泡排序
/// <summary>
/// 冒泡排序
/// </summary>
/// <param name="array"></param>
void BubleSort(int[] array) {
//最后一个数字不需要计算了
for (int i = 0; i < array.Length-1; i++)
{
//剩余的数字 左右对比 左边>右边则交换
//第一次循环后 最右边一定是最大值
//缩小范围重复此过程
for (int j = 0; j < array.Length-1-i; j++)
{
if (array[j]>array[j+1])
{
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
归并排序
/// <summary>
/// 归并排序
/// 将数组平均划分成两部分,【递归此方法】,直到每个部分只有一个数字
/// 递归划分后执行以下逻辑
/// 两部分从左到右对比,把小的数字放在辅助数组前面
/// 直到两个部分没有数字
/// 将辅助数组中的结果赋值到排序数组里
/// </summary>
/// <param name="array">需要排序的数组</param>
/// <param name="array1">辅助数组</param>
/// <param name="startIndex">当前左下标</param>
/// <param name="endIndex">当前右下标</param>
void MergeSort(int[] array, int[] array1, int startIndex, int endIndex)
{
if (startIndex>=endIndex)
{
return;
}
//计算中间下标
int middle = (startIndex + endIndex) / 2;
//分治 将数组分为0,middle 与 middle+1,length-1 两部分
MergeSort(array, array1, startIndex, middle);
MergeSort(array, array1, middle + 1, endIndex);
int left = startIndex;//左半区间的左下标
int left1 = middle+1;//右半区间的左下标
int left2 = startIndex;//辅助数组的左下标
//左区间左下标不超过middle , 右区间左下标不超过endIndex
while (left <= middle || left1 <= endIndex)
{
//从分割开的两个区域中 分别取第一个数字进行比较 小的数字放入辅助数组中 并缩小范围
//left1>endIndex时array[left1]已经越界了,加入这个判断避免执行 array[left]<array[left1]
if (left1 > endIndex || array[left] < array[left1])
array1[left2++] = array[left++];
else
array1[left2++] = array[left1++];
}
//将结果赋给array 保存本次结果
for (left = startIndex; left <= endIndex; left++)
array[left] = array1[left];
}
希尔排序
/// <summary>
/// 希尔排序
/// 类似归并排序 将数组划分为间隔为2的组 对每一组进行排序
/// 逐渐增加间隔 最后整个数组只有一组时 排序结束
/// </summary>
/// <param name="a"></param>
/// <param name="n"></param>
void ShellSort(int[] a)
{
//将原始数组除以2的数量作为分组的数量,做一次排序,重复到group只有一组
//group也是各个组之间成员的间隔
for (int group = a.Length / 2; group >= 1; group /= 2)
{
//把每个分组的第一个数字看做已排序 从a[group]开始进行插入排序
for (int i = group; i < a.Length; i++)
{
//简化版的插入排序 对组内成员进行
for (int j = i-group; j >=0 && a[j]>a[j+group] ; j-=group)
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
堆排序
/// <summary>
/// 堆排序
/// 堆排序涉及完全二叉树的特性,第一次接触的萌新要补补课
/// 堆排序把数组做成大根堆,然后把根与最小叶节点交换 , 然后缩小范围
/// 对剩余的二叉树继续调整为大根堆,然后首尾交换,最后得到排序后的数组
/// </summary>
/// <param name="array"></param>
void HeapSort(int[] array)
{
//从右向左 从下到上 遍历非叶节点
for (int i = array.Length / 2 - 1; i >= 0; i--)
{
AdjustHeap(array, i, array.Length-1);
}
//交换出最大数字,调成剩余的树
for (int i = array.Length - 1; i > 0; i--)
{
int temp = array[0];
array[0] = array[i];
array[i] = temp;
AdjustHeap(array, 0, i-1);
}
}
/// <summary>
/// 调整
/// </summary>
/// <param name="array"></param>
/// <param name="startIndex">根下标</param>
/// <param name="endIndex">最后一个叶子下标</param>
void AdjustHeap(int[] array, int startIndex, int endIndex)
{
//保存根节点值
int temp = array[startIndex];
//从左树开始计算
for (int i = startIndex * 2 + 1; i <= endIndex; i = i * 2 + 1)
{
//左树小于右树
if (i + 1 < endIndex && array[i] < array[i + 1])
{
i++;//i指向右树
}
//以下是一个移动的方式 将temp插入
//当前节点大于最初的根节点
if (array[i] > temp)
{
//移动的方式排序
array[startIndex] = array[i];
//调整根位置
startIndex = i;
}
//没有调整 子节点叶不需要调整了
else
{
break;
}
}
//将最初根节点的值插入
array[startIndex] = temp;
}
lua版
最近在熟悉lua,顺手用lua写了一遍加强记忆,原理和上面一样就不赘述了。
--冒泡排序
function bubleSort(array)
for i=1,#array-1 do
for j=1,#array-i do
if array[j]>array[j+1] then
array[j],array[j+1]=array[j+1],array[j];
end
end
end
end
--插入排序
function insertSort(array)
for i=2,#array do
for j=i,2,-1 do
if array[j]<array[j-1] then
array[j],array[j-1]=array[j-1],array[j];
end
end
end
end
--选择排序
function selectSort(array)
for i=1,#array do
local min=i;
for j=i,#array do
if array[j]<array[min] then
min=j;
end
end
if i~=min then
array[i],array[min]=array[min],array[i];
end
end
end
--快速排序
function quickSort(array,startI,endI)
if startI>=endI then
return;
end
local baseInt=array[startI];
local leftTemp=startI;
local rightTemp=endI;
while (leftTemp<rightTemp) do
while (leftTemp<rightTemp and array[rightTemp]>=baseInt) do
rightTemp=rightTemp-1;
end
array[leftTemp]=array[rightTemp];
while (leftTemp<rightTemp and array[leftTemp]<=baseInt) do
leftTemp=leftTemp+1;
end
array[rightTemp]=array[leftTemp];
end
array[leftTemp]=baseInt;
quickSort(array,startI,leftTemp-1);
quickSort(array,leftTemp+1,endI);
end
--希尔排序 lua相除得到的是浮点型 坑 自己取整
function shellSort(array)
local i=math.modf(#array/2);
while(i>=1) do
for j=i+1,#array do
local k=j;
while(k-i>=1) do
if (array[k]<array[k-i]) then
array[k],array[k-i]=array[k-i],array[k];
end
k=k-i;
end
end
i=math.modf(i/2);
end
end
--归并排序
function mergeSort(array,startI,endI,arrayTemp)
if array==nil or startI >= endI then
return;
end
local middle=math.modf((startI+endI)/2);
local leftTemp=startI;
local leftTemp1=middle+1;
local leftTemp2=startI;
mergeSort(array,startI,middle,arrayTemp);
mergeSort(array,leftTemp1,endI,arrayTemp);
while (leftTemp<=middle or leftTemp1<=endI) do
if leftTemp1>endI or array[leftTemp]<array[leftTemp1] then
arrayTemp[leftTemp2]=array[leftTemp];
leftTemp=leftTemp+1;
leftTemp2=leftTemp2+1;
else
arrayTemp[leftTemp2]=array[leftTemp1];
leftTemp1=leftTemp1+1;
leftTemp2=leftTemp2+1;
end
end
for i=startI,endI do
array[i]=arrayTemp[i];
end
end
--堆排序
function heapSort(array)
funcHeapSort=function(array,startI,endI)
local i=startI*2;
local temp=array[startI];
while(i<=endI) do
if i+1<=endI and array[i+1]>array[i] then
i=i+1;
end
if array[i]>temp then
array[startI]=array[i];
startI=i;
else
break;
end
i=i*2;
end
array[startI]=temp;
end
for i=math.modf(#array/2),1,-1 do
funcHeapSort(array,i,#array);
end
for i=#array,2,-1 do
array[1],array[i]=array[i],array[1];
funcHeapSort(array,1,i-1);
end
end
--二分查找法
function binarySearch(array,target)
if array==nil then
return;
end
local startI=1;
local endI=#array;
while (startI<endI) do
local middle=math.modf((startI+endI)/2);
if target<array[middle] then
endI=middle-1;
elseif target>array[middle] then
startI=middle+1;
else
print("found it");
return;
end
end
print("not found");
end