第5节、插入排序
遍历每个数使其左边的数变成成有序态。遍历左边的数如果左边的时候大于右边,那就交换。
插入排序的时间复杂度。最差复杂度为O(N^2)。最好是复杂度为O(N)。
namespace LeetCode_Learn
{
/// <summary>
/// 插入排序
/// </summary>
public class Part05_InsertSort
{
public static int[] Sort(int[] arr)
{
if (arr == null)
throw new ArgumentNullException("arr不可为空!");
if (arr.Length < 2)
return arr;
for (int i = 1; i < arr.Length; i++)
{
for (int j = i - 1; j >= 0; j--)
{
if (arr[j] > arr[j + 1])
{
Swap(arr, j, j + 1);
}
}
}
return arr;
}
private static void Swap(int[] arr, int index1, int index2)
{
arr[index1] = arr[index1] ^ arr[index2];
arr[index2] = arr[index1] ^ arr[index2];
arr[index1] = arr[index1] ^ arr[index2];
}
}
}
第6节、二分法
-
有序数组中的二分法。在有序数组中的一个数是否存在?时间复杂度为big,log2为底的N次方。
-
有序数组中找大于等于某个数最左侧的位置。与上题相同,不过要二分到最左侧的位置。
public class Part06_BSOne { public static int Get(int[] arr, int num) { if (arr == null) throw new ArgumentNullException("arr不可为空!"); if (arr.Length < 2) return arr[0]; return binaryFindNum(arr,0, arr.Length - 1,num); } public static int binaryFindNum(int[] arr, int left, int right, int num) { if (left > right)//递归结束 return -1; int mid = (left + right) / 2; int midVal = arr[mid]; if (num > midVal) return binaryFindNum(arr, mid + 1, right, num);//向右递归 else if (num < midVal) return binaryFindNum(arr, left, mid - 1, num);//向左递归 else return mid; } }
-
局部最小问题。
public class Part06_BSOneLeftNear { public static int Get(int[] arr, int num) { if (arr == null) throw new ArgumentNullException("arr不可为空!"); if (arr.Length < 2) return arr[0]; return binary(arr, 0, arr.Length - 1, num); } public static int binary(int[] arr, int left, int right, int num) { if (left > right)//递归结束 return -1; int mid = (left + right) / 2; int midVal = arr[mid]; //如果当前中间值>=num且左边元素也>=num,则向左递归 if (mid - 1 >= 0 && midVal >= num && arr[mid - 1] >= num) return binary(arr, left, mid - 1, num);//向左递归 //如果当前中间值>=num但左边元素<num,则直接返回该中间值 else if (mid - 1 >= 0 && midVal >= num && arr[mid - 1] < num) return mid; //其他情况向右递归 else return binary(arr, mid + 1, right, num);//向右递归 } }
第7节、对数器
实现一个简单的C#对数器,实现排序算法对比
namespace LeetCode_Learn
{
public class Compare
{
public static void DO(int number, Action<int[]> CustomSort, int length, int min, int max)
{
if (number == 0) return;
for (int i = 0; i < number; i++)
{
DO(CustomSort, length, min, max);
}
}
static bool DO(Action<int[]> CustomSort, int length, int min, int max)
{
int[] arr = new int[length];
RandomArr(arr, length, min, max);
int[] arr1 = new int[length];
Array.Copy(arr, arr1, length);
int[] arr2 = new int[length];
Array.Copy(arr, arr2, length);
Array.Sort(arr1);
CustomSort(arr2);
if (!Do(arr1, arr2, length))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"错误样本{string.Join(", ", arr)}");
Console.WriteLine($"错误样本排序: {string.Join(", ", arr2)}");
Console.WriteLine("\n");
return false;
}
else
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"正确样本{string.Join(", ", arr)}");
Console.WriteLine($"正确样本排序{string.Join(", ", arr2)}");
Console.WriteLine("\n");
};
Console.ForegroundColor = ConsoleColor.White;
return true;
}
static bool Do(int[] arr1, int[] arr2, int length)
{
bool right = true;
for (int i = 0; i < length; i++)
{
if (arr1[i] == arr2[i])
{
}
else
{
right = false;
};
}
return right;
}
static void RandomArr(int[] arr, int length, int min, int max)
{
Random rand = new Random();
for (int i = 0; i < length; i++)
{
arr[i] = rand.Next(min, max);
}
}
}
}