三、排序算法(基础)
一、冒泡排序
原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,
这样一趟过去后,最大或最小的数字被交换到了最后一位,
然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子
例子为从小到大排序,
原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |
第一趟排序(外循环)
第一次两两比较6 > 2交换(内循环)
交换前状态| 6 | 2 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |
第二次两两比较,6 > 4交换
交换前状态| 2 | 6 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |
第三次两两比较,6 > 1交换
交换前状态| 2 | 4 | 6 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |
以此类推
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication9 { /// <summary> /// 算法 /// </summary> public class Algorithm { #region 冒泡排序 /// <summary> /// 冒泡排序 /// </summary> public void BubbleSortAsc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0); for (int i = 0; i <= count; i++) { for (int j = i + 1; j <= count; j++) { if (array[i].CompareTo(array[j]) == 1) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } /// <summary> /// 冒泡排序 /// </summary> public void BubbleSortDesc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0); for (int i = 0; i <= count; i++) { for (int j = i + 1; j <= count; j++) { if (array[i].CompareTo(array[j]) == -1) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } #endregion } }
static void Main(string[] args) { Algorithm algorithm = new Algorithm(); int[] array = new int[] { 8, 3, 5, 6, 7 }; string[] str = new string[] { "fa", "qw", "ac" }; algorithm.BubbleSortDesc<string>(str); foreach (var item in str) { Console.WriteLine(item); } }
二、选择排序
选择排序和冒泡排序差不多,原理:
1.外层循环从0开始循环到数组最末尾一个,内层循环从外层循环的后一位开始循环到数组最末尾
2.假设外层 i 是最小的一个元素,记住下标。然后遍历内层(i+1)开始一直到数组末尾,选择出最小的一个元素的下标。
3.如果最小的下标不是 i 那么交换值
public void SelectionSortAsc<T>(T[] array) where T : IComparable<T> { T temp; int min, count = array.GetUpperBound(0); ; for (int i = 0; i <= count; i++) { min = i; for (int j = i + 1; j <= count; j++) { if (array[j].CompareTo(array[min]) == -1) min = j; } if (i != min) { temp = array[i]; array[i] = array[min]; array[min] = temp; } } }
三、插入排序
从数组的第二个元素开始,与它前一个元素进行比较。假设前一个元素大于当前元素,那么把当前元素拿出来,前一个元素后移,在继续和前前元素进行比较,直到前面没有元素比它大,那么这个位置就是最合适的。
/// <summary> /// 插入排序 /// </summary> public void InsertionSortAsc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0), j; for (int i = 1; i <= count; i++) { if (array[i].CompareTo(array[i - 1]) == -1)//array[i] < array[i-1] { //当前元素比前一个数小,那么先把当前数和当前元素所在位置拿出来 temp = array[i]; j = i; //然后用 temp和它前面的元素比较,如果 temp<它前面的元素 那么前面的元素都往后移动一位。 while (j > 0 && temp.CompareTo(array[j - 1]) == -1) { array[j] = array[j - 1]; //往后移位 j--; } //空出来一个最合适的位置,把temp放入 array[j] = temp; } } }
四、比较性能
三种算法的完整代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication9 { /// <summary> /// 算法 /// </summary> public class Algorithm { #region 冒泡排序 /// <summary> /// 冒泡排序 /// </summary> public void BubbleSortAsc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0); for (int i = 0; i <= count; i++) { for (int j = i + 1; j <= count; j++) { if (array[i].CompareTo(array[j]) == 1) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } /// <summary> /// 冒泡排序 /// </summary> public void BubbleSortDesc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0); for (int i = 0; i <= count; i++) { for (int j = i + 1; j <= count; j++) { if (array[i].CompareTo(array[j]) == -1) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } #endregion #region 选择排序 /// <summary> /// 选择排序 /// </summary> public void SelectionSortAsc<T>(T[] array) where T : IComparable<T> { T temp; int min, count = array.GetUpperBound(0); ; for (int i = 0; i <= count; i++) { min = i; for (int j = i + 1; j <= count; j++) { if (array[j].CompareTo(array[min]) == -1) min = j; } if (i != min) { temp = array[i]; array[i] = array[min]; array[min] = temp; } } } /// <summary> /// 选择排序 /// </summary> public void SelectionSortDesc<T>(T[] array) where T : IComparable<T> { T temp; int max, count = array.GetUpperBound(0); ; for (int i = 0; i <= count; i++) { max = i; for (int j = i + 1; j <= count; j++) { if (array[j].CompareTo(array[max]) == 1) max = j; } if (i != max) { temp = array[i]; array[i] = array[max]; array[max] = temp; } } } #endregion #region 插入排序 /// <summary> /// 插入排序 /// </summary> public void InsertionSortAsc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0), j; for (int i = 1; i <= count; i++) { if (array[i].CompareTo(array[i - 1]) == -1)//array[i] < array[i-1] { //当前元素比前一个数小,那么先把当前数和当前元素所在位置拿出来 temp = array[i]; j = i; //然后用 temp和它前面的元素比较,如果 temp<它前面的元素 那么前面的元素都往后移动一位。 while (j > 0 && temp.CompareTo(array[j - 1]) == -1) { array[j] = array[j - 1]; //往后移位 j--; } //空出来一个最合适的位置,把temp放入 array[j] = temp; } } } /// <summary> /// 插入排序 /// </summary> public void InsertionSortDesc<T>(T[] array) where T : IComparable<T> { T temp; int count = array.GetUpperBound(0), j; for (int i = 1; i <= count; i++) { if (array[i].CompareTo(array[i - 1]) == 1)//array[i] > array[i-1] { //当前元素比前一个数大,那么先把当前数和当前元素所在位置拿出来 temp = array[i]; j = i; //然后用 temp和它前面的元素比较,如果 temp>它前面的元素 那么前面的元素都往后移动一位。 while (j > 0 && temp.CompareTo(array[j - 1]) == 1) { array[j] = array[j - 1]; //往后移位 j--; } //空出来一个最合适的位置,把temp放入 array[j] = temp; } } } #endregion } }
性能测试类:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication9 { public class Timing { TimeSpan duration; public Timing() { duration = new TimeSpan(0); } public void stopTime() { duration = Process.GetCurrentProcess().TotalProcessorTime; } public void startTime() { GC.Collect(); GC.WaitForPendingFinalizers(); } public TimeSpan Result() { return duration; } } }
主函数:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication9 { class Program { static void Main(string[] args) { int count=100; int[] array = new int[count]; Timing timing = new Timing(); Algorithm algorithm = new Algorithm(); //测试冒泡排序耗时 init(array, count); timing.startTime(); algorithm.BubbleSortAsc(array); timing.stopTime(); Console.WriteLine("Time for BubbleSort:" + timing.Result().TotalMilliseconds); //测试选择排序耗时 clear(array, count); init(array, count); timing.startTime(); algorithm.SelectionSortAsc(array); timing.stopTime(); Console.WriteLine("Time for SelectionSort:" + timing.Result().TotalMilliseconds); //测试插入排序 clear(array, count); init(array, count); timing.startTime(); algorithm.InsertionSortAsc(array); timing.stopTime(); Console.WriteLine("Time for InsertingSort:" + timing.Result().TotalMilliseconds); } static void init(int[] array, int count) { Random random = new Random(); for (int i = 0; i < count; i++) { array[i] = random.Next(0, count); } } static void clear(int[] array, int count) { for (int i = 0; i < count; i++) { array[i] =0; } } } }
或者使用C#自带的System.Diagnostics.Stopwatch函数进行耗时测试,该函数内部使用win32api Kernel32
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication9 { class Program { static void Main(string[] args) { int count=10000; int[] array = new int[count]; int[] backups = new int[count]; System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); Algorithm algorithm = new Algorithm(); init(array, count); array.CopyTo(backups, 0); //测试选择排序耗时 stopwatch.Start(); algorithm.SelectionSortAsc(array); stopwatch.Stop(); Console.WriteLine("Time for SelectionSort:" + stopwatch.Elapsed.TotalMilliseconds); //测试冒泡排序耗时 backups.CopyTo(array, 0); stopwatch.Start(); algorithm.BubbleSortAsc(array); stopwatch.Stop(); Console.WriteLine("Time for BubbleSort:" + stopwatch.Elapsed.TotalMilliseconds); //测试插入排序 backups.CopyTo(array, 0); stopwatch.Start(); algorithm.InsertionSortAsc(array); stopwatch.Stop(); Console.WriteLine("Time for InsertingSort:" + stopwatch.Elapsed.TotalMilliseconds); } static void init(int[] array, int count) { Random random = new Random(); for (int i = 0; i < count; i++) { array[i] = random.Next(0, count); } } static void clear(int[] array, int count) { for (int i = 0; i < count; i++) { array[i] =0; } } } }


浙公网安备 33010602011771号