1. 程式人生 > >C#中常見的幾種陣列排序例項

C#中常見的幾種陣列排序例項

1、氣泡排序

冒泡是最常用的排序方法之一,它在第一次排序的時候將每一條記錄的關鍵字進行比較,直到n-1個記錄和n個記錄的關鍵字比較完成為止,再進行下一次排序,直到n-1趟記錄為止

        class BubbleSorter
        /// <summary>
        /// 氣泡排序
        /// </summary>
        public void Sort(int[] list)
        {
            int i, j, temp;
            bool done = false;
            j = 1; while ((j < list.Length) && (!done))//判斷長度
            {
                done = true;
                for (i = 0; i < list.Length - j; i++)
                {
                    if (list[i] > list[i + 1])
                    {
                        done = false;
                        temp = list[i];
                        list[i] = list[i + 1];//交換資料 
                        list[i + 1] = temp;
                    }
                }
                j++;
            }
        } 

2、選擇排序

選擇排序的思路是:每趟在n個記錄中選取關鍵字最小的那個作為有序序列的第一個記錄,並且以1~(n-1)進行(n-1)趟選擇操作

 class SelectionSorter
    {
        private int min;
        /// <summary>
        /// 選擇排序
        /// </summary>
        public void Sort(int[] list)
        {
            for (int i = 0; i < list.Length - 1; i++)
            {
                min = i;
                for (int j = i + 1; j < list.Length; j++)
                {
                    if (list[j] < list[min])
                        min = j;
                }
                int t = list[min];
                list[min] = list[i];
                list[i] = t;
            }
        }
    }

3、插入排序

將資料放入有序序列當中,找到比要插入的資料大和小的兩個資料,然後插入它們中間

 class InsertionSorter
    {
        /// <summary>
        /// 插入排序
        /// </summary>
        public void Sort(int[] list)
        {
            for (int i = 1; i < list.Length; i++)
            {
                int t = list[i];
                int j = i;
                while ((j > 0) && (list[j - 1] > t))
                {
                    list[j] = list[j - 1];
                    --j;
                }
                list[j] = t;
            }
        }
    }

4、快速排序

通過選取一個關鍵資料(通常是選第一個記錄),然後再將比它小的資料排在關鍵字的前面,比它大的資料排在後面,遞迴呼叫

     //交換資料
        private void swap(ref int l, ref int r)
        {
            int temp;//臨時值
            temp = l;//記錄前一個值
            l = r;//記錄後一個值
            r = temp;//前後交換資料
        }

         private void Sort(int[] list, int row, int cell)
        {
            int pivot;//臨時變數,用來儲存最大值
            int l, r;//分別用來記錄遍歷到的索引和最大索引
            int mid;//中間索引
            if (cell <= row)//判斷輸入的值是否合法
                return;
            else if (cell == row + 1)//判斷兩個索引是否相鄰
            {
                if (list[row] > list[cell])//判斷前面的值是否大於後面的值
                    swap(ref list[row], ref list[cell]);//交換前後索引的值
                return;
            }
            mid = (row + cell) >> 1;//記錄陣列的中間索引
            pivot = list[mid];//初始化臨時變數的值
            swap(ref list[row], ref list[mid]);//交換第一個值和中間值的索引順序
            l = row + 1;//記錄遍歷到的索引值
            r = cell;//記錄最大索引
            try
            {
                //使用do...while迴圈遍歷陣列,並比較前後值的大小
                do
                {

                    while (l <= r && list[l] < pivot)//判斷遍歷到的索引是否小於最大索引
                        l++;//索引值加1
                    while (list[r] >= pivot)//判斷最大值是否大於等於記錄的分支點
                        r--;//做大索引值減1
                    if (l < r)//如果當前遍歷到的值小於最大值
                        swap(ref list[l], ref list[r]);//交換順序

                } while (l < r);
                list[row] = list[r];//在最小索引處記錄最小值
                list[r] = pivot;//在最大索引處記錄最大值
                if (row + 1 < r)//判斷最小索引是否小於最大索引
                    Sort(list, row, r - 1);//呼叫自身進行快速排序
                if (r + 1 < cell)//判斷最大索引是否小於陣列長度
                    Sort(list, r + 1, cell);//呼叫自身進行快速排序
            }
            catch { }
        }

5、希爾排序

先將有個待排序的序列分割成若干個小序列,然後分別進行插入排序,待整個序列基於有序時再將整個序列進行一次插入排序。

子序列分割不是簡單的“段落分割”,而是將相隔某個“增量”的陣列成一個子序列。

class ShellSorter
        {
            /// <summary>
            /// 希爾排序
            /// </summary>
            public void Sort(int[] list)
            {
                int inc;
                for (inc = 1; inc <= list.Length / 9; inc = 3 * inc + 1) ;
                for (; inc > 0; inc /= 3)
                {
                    for (int i = inc + 1; i <= list.Length; i += inc)
                    {
                        int t = list[i - 1];
                        int j = i;
                        while ((j > inc) && (list[j - inc - 1] > t))
                        {
                            list[j - 1] = list[j - inc - 1];
                            j -= inc;
                        }
                        list[j - 1] = t;
                    }
                }
            }

        }