三、排序算法(基础)

一、冒泡排序

原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,

这样一趟过去后,最大或最小的数字被交换到了最后一位,

然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子

例子为从小到大排序,

原始待排序数组| 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
    }
}
View Code

性能测试类:

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;
        }
    }
}
View Code

主函数:

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;
            }
        }
    }
}
View Code

 或者使用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;
            }
        }
    }
}
View Code

 

posted @ 2016-04-07 19:18  HUCEMAIL  阅读(89)  评论(0)    收藏  举报