在这里,我已经为下面的算法准备了我的解决方案,并且好奇是否有一种方法来优化它们。欢迎并感谢您的任何意见!
using System;
using System.Collections.Generic;
using System.Linq;
namespace algotest
{
class Program
{
static void InsertionSort(int[] arr)
{
for (int i = 1; i < arr.Length; ++i)
{
int temp = arr[i];
bool sorted = false;
for (int j = i - 1; j >= 0 && !sorted;)
{
if (temp < arr[j])
{
arr[j + 1] = arr[j];
--j;
arr[j + 1] = temp;
}
else
{
sorted = true;
}
}
}
}
static void BubbleSort(int[] arr)
{
int temp = 0;
for (int i = 0; i < arr.Length; ++i)
{
for (int j = 0; j < arr.Length - 1; ++j)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
static void SelectionSort(int[] arr)
{
int temp, min;
for (int i = 0; i < arr.Length - 1; ++i)
{
min = i;
for (int j = i + 1; j < arr.Length; ++j)
{
if (arr[j] < arr[min])
{
min = j;
}
}
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
static void Merge(int[] arr, int left, int pivot, int right)
{
int[] temp = new int[25];
int index = left;
int leftBound = pivot - 1;
int length = right - left + 1;
while (left <= leftBound && pivot <= right)
{
if (arr[left] <= arr[pivot])
{
temp[index++] = arr[left++];
}
else
{
temp[index++] = arr[pivot++];
}
}
while (left <= leftBound)
{
temp[index++] = arr[left++];
}
while (pivot <= right)
{
temp[index++] = arr[pivot++];
}
for (int i = 0; i < length; i++)
{
arr[right] = temp[right];
right--;
}
}
static void MergeSort(int[] arr, int left, int right)
{
if (right > left)
{
int pivot = (right + left) / 2;
MergeSort(arr, left, pivot);
MergeSort(arr, pivot + 1, right);
Merge(arr, left, pivot + 1, right);
}
}
static void QuickSort(int[] arr, int left, int right)
{
int i = left, j = right;
int pivot = arr[(left + right) / 2];
while (i <= j)
{
while (arr[i].CompareTo(pivot) < 0)
{
++i;
}
while (arr[j].CompareTo(pivot) > 0)
{
--j;
}
if (i <= j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
++i;
--j;
}
}
if (left < j)
{
QuickSort(arr, left, j);
}
if (i < right)
{
QuickSort(arr, i, right);
}
}
static void Heapify(int[] arr, int i, int n)
{
try
{
int temp = arr[i];
int j = 2 * i;
while (j <= n)
{
if (j < n && arr[j] < arr[j + 1])
{
j++;
}
if (temp >= arr[j])
{
break;
}
arr[j / 2] = arr[j];
j *= 2;
}
arr[j / 2] = temp;
}
catch (IndexOutOfRangeException err)
{
Console.WriteLine("Array Out of Bounds ", err);
}
}
static void HeapSort(int[] arr)
{
for (int i = arr.Length / 2; i >= 0; --i)
{
Heapify(arr, i, arr.Length - 1);
}
for (int i = arr.Length - 2; i >= 0; --i)
{
int temp = arr[i + 1];
arr[i + 1] = arr[0];
arr[0] = temp;
Heapify(arr, 0, i);
}
}
static void CountingSort(int[] arr)
{
int[] count = new int[arr.Max() + 1];
for (int i = 0; i < arr.Length; ++i)
{
++count[arr[i]];
}
int j = 0;
for (int i = 0; i < count.Length; ++i)
{
for (int k = 0; k < count[i]; ++k)
{
arr[j++] = i;
}
}
}
static void RadixSort(int[] arr)
{
int i, j;
int[] temp = new int[arr.Length];
for (int shift = 31; shift > -1; --shift)
{
j = 0;
for (i = 0; i < arr.Length; ++i)
{
bool move = (arr[i] << shift) >= 0;
if (shift == 0 ? !move : move)
{
arr[i - j] = arr[i];
}
else
{
temp[j++] = arr[i];
}
}
Array.Copy(temp, 0, arr, arr.Length - j, j);
}
}
static void BucketSort(int[] arr)
{
// bucket size key:
// array 1-99 ; 10 buckets
// arrat 100-199 ; 20 buckets
// etc.
// TODO: Implement logic to determine bucket size?
int numOfBuckets = 10;
List<int> result = new List<int>();
List<int>[] buckets = new List<int>[numOfBuckets];
for (int i = 0; i < numOfBuckets; ++i)
{
buckets[i] = new List<int>();
}
for (int i = 0; i < arr.Length; ++i)
{
int index = arr[i] / numOfBuckets;
buckets[index].Add(arr[i]);
}
for (int i = 0; i < numOfBuckets; ++i)
{
int[] temp = buckets[i].ToArray();
InsertionSort(arr);
result.AddRange(temp);
}
arr = result.ToArray();
}
static void Main(string[] args)
{
Console.WriteLine("Please select an algorithm: ");
Console.WriteLine("I : InsertionSort O(n^2)");
Console.WriteLine("B : BubbleSort O(n^2)");
Console.WriteLine("S : SelectionSort O(n^2)");
Console.WriteLine("M : MergeSort O(nlgn)");
Console.WriteLine("Q : QuickSort O(nlgn)");
Console.WriteLine("H : HeapSort O(nlgn)");
Console.WriteLine("C : CountingSort O(n)");
Console.WriteLine("R : RadixSort O(n)");
Console.WriteLine("U : BucketSort O(n)");
string algorithm = Console.ReadLine().ToUpper();
Console.WriteLine("How many elements?");
int numOfElements = int.Parse(Console.ReadLine());
int[] arr = new int[numOfElements];
Random rand = new Random();
Console.WriteLine("Generating random data...");
for (int i = 0; i < numOfElements; ++i)
{
arr[i] = rand.Next(100);
}
switch (algorithm)
{
case "I":
InsertionSort(arr);
break;
case "B":
BubbleSort(arr);
break;
case "S":
SelectionSort(arr);
break;
case "M":
MergeSort(arr, 0, arr.Length - 1);
break;
case "Q":
QuickSort(arr, 0, arr.Length - 1);
break;
case "H":
HeapSort(arr);
break;
case "C":
CountingSort(arr);
break;
case "R":
RadixSort(arr);
break;
case "U":
BucketSort(arr);
break;
}
for (int i = 0; i < arr.Length; ++i)
{
Console.WriteLine(arr[i]);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}发布于 2017-09-22 21:50:31
您不需要标志变量sorted。而不是sorted = true,您可以简单地将break从循环中剔除。
可以避免多次标记变量,从而产生更简单、更易读的解决方案。始终以可疑的方式查看标志变量。
int[] temp = new int[25]中的数字25看起来是任意的。为什么是25?
请注意,这可能导致整数溢出,这是合并排序实现中的一个常见缺陷:
int枢轴=(右+左)/ 2;
修复方法非常简单:
int pivot = left + (right - left) / 2;实现分配一个大小为arr.Max() + 1的数组作为存储。最好也考虑到arr.Min(),以避免分配超出必要的空间。
此外,如果输入包含负数,当前的实现将崩溃。这也是考虑arr.Min()的另一个原因。
发布于 2017-09-23 06:11:53
您似乎在反复编写不需要的移动元素,而且正如前面提到的,有一个不需要的sorted标志,因此您可以从循环中跳出,放置移动元素。
static void InsertionSort(int[] arr)
{
for (int i = 1; i < arr.Length; ++i)
{
int temp = arr[i];
int j = i - 1;
while (j >= 0)
{
if (temp >= arr[j]) break; // found insertion point
arr[j + 1] = arr[j];
--j;
}
arr[j + 1] = temp;
}
}通常,气泡排序指的是交换相邻元素。可以通过跟踪上一个交换来优化它。
static void BubbleSort(int[] arr)
{
int endPt = arr.Length - 1;
while (endPt > 0)
{
int lastSwap = 0;
for (int j = 0; j < endPt; ++j)
{
if (arr[j] > arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
lastSwap = j;
}
}
endPt = lastSwap;
}
}没有任何问题,尽管您的变量声明距离它们的使用点比前面的例程稍微远一点。
..。我以后可能会再看看。
https://codereview.stackexchange.com/questions/176340
复制相似问题