1. 程式人生 > >基礎排序演算法(三)——對半插入排序

基礎排序演算法(三)——對半插入排序

之前的文章介紹了氣泡排序和插入排序,這裡再補充一個對半插入排序演算法,它與對半查詢演算法(二分查詢演算法)有點相似之處。

還是先上程式碼:

        public void HalfInsertSort(int[] array)
        {
            int j = 0, temp, low, high, mid;
            int count = array.Length;
            for (int i = 1; i < count; i++)
            {
                temp = array[i];
                low = 0;
                high = i - 1;
                while (low <= high)
                {
                    mid = (low + high) / 2;
                    if (temp < array[mid]) high = mid - 1;
                    else low = mid + 1;
                }
                for (j = i - 1; j >= low; j--) array[j + 1] = array[j];
                array[low] = temp;
            }
        }
在Program的Main函式裡New一個(一)中寫的那個CSharpArray類,呼叫其中的方法測試:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BasicStructure
{
    class Program
    {
        static void Main(string[] args)
        {
            CSharpArray csharArray = new CSharpArray(8);
            int[] array = csharArray.getArray();
            Console.WriteLine("排序前:");
            Console.WriteLine();
            csharArray.PrintArray(array);
            Console.WriteLine();
            Console.WriteLine("排序後:");
            csharArray.HalfInsertSort(array);
            csharArray.PrintArray(array);

            Console.ReadKey();
        }
    }
}
輸出結果:

排序前:
        1       0       2       5       4       1       3       4
排序後:
        0       1       1       2       3       4       4       5
為了顯示for迴圈中的每次執行結果,在HalfInsertSort方法里加一句輸出:

        public void HalfInsertSort(int[] array)
        {
            int j = 0, temp, low, high, mid;
            int count = array.Length;
            for (int i = 1; i < count; i++)
            {
                temp = array[i];
                low = 0;
                high = i - 1;
                while (low <= high)
                {
                    mid = (low + high) / 2;
                    if (temp < array[mid]) high = mid - 1;
                    else low = mid + 1;
                }
                for (j = i - 1; j >= low; j--) array[j + 1] = array[j];
                array[low] = temp;
                PrintArray(array);
            }
        }
再次編譯執行即得以下結果:

排序前:
        1       0       2       5       4       1       3       4
排序後:
        0       1       2       5       4       1       3       4
        0       1       2       5       4       1       3       4
        0       1       2       5       4       1       3       4
        0       1       2       4       5       1       3       4
        0       1       1       2       4       5       3       4
        0       1       1       2       3       4       5       4
        0       1       1       2       3       4       4       5
        0       1       1       2       3       4       4       5
從輸出結果可以看出,遍歷陣列元素,利用對半查詢原理找到其位置,插入,將受影響的元素一次前移。

同樣,為了將以上的升序排序演算法改為降序,也只需將while括號裡的大於號改為小於號即可。


這裡,既然將其封裝在一個類裡,自然要提高其通用性,因此,我可以再給改排序演算法新增一個引數,用來標記是升序排序還是降序排序。如:用“0”表示升序,用“1”表示降序,在不降低程式碼執行效率時以犧牲程式碼簡潔性來修改一下程式碼:

        public void HalfInsertSort(int[] array, int orderType)
        {
            int j = 0, temp,low,high,mid;
            int count = array.Length;
            if (orderType == 0)
            {
                for (int i = 1; i < count; i++)
                {
                    temp = array[i];
                    low = 0;
                    high = i - 1;
                    while (low <= high)
                    {
                        mid = (low + high) / 2;
                        if (temp < array[mid]) high = mid - 1;
                        else low = mid + 1;
                    }
                    for (j = i - 1; j >= low; j--) array[j + 1] = array[j];
                    array[low] = temp;
                    PrintArray(array);
                }
            }
            else if (orderType == 1)
            {
                for (int i = 1; i < count; i++)
                {
                    temp = array[i];
                    low = 0;
                    high = i - 1;
                    while (low < high)
                    {
                        mid = (low + high) / 2;
                        if (temp > array[mid]) high = mid - 1;
                        else low = mid + 1;
                    }
                    for (j = i - 1; j >= low; j--) array[j + 1] = array[j];
                    array[low] = temp;
                    PrintArray(array);
                }
            }
        }
再修改Main函式裡程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BasicStructure
{
    class Program
    {
        static void Main(string[] args)
        {
            CSharpArray csharArray = new CSharpArray(8);
            int[] array = csharArray.getArray();
            Console.WriteLine("排序前:");
            Console.WriteLine();
            csharArray.PrintArray(array);
            Console.WriteLine();
            Console.WriteLine("升序排序後:");
            csharArray.HalfInsertSort(array, 0);
            csharArray.PrintArray(array);
            Console.WriteLine("降序排序後:");
            csharArray.HalfInsertSort(array, 1);
            csharArray.PrintArray(array);

            Console.ReadKey();
        }
    }
}
編譯執行結果如下所示:

排序前:
        2       4       0       3       5       6       1       1
升序排序後:
        2       4       0       3       5       6       1       1
        0       2       4       3       5       6       1       1
        0       2       3       4       5       6       1       1
        0       2       3       4       5       6       1       1
        0       2       3       4       5       6       1       1
        0       1       2       3       4       5       6       1
        0       1       1       2       3       4       5       6
        0       1       1       2       3       4       5       6
降序排序後:
        1       0       1       2       3       4       5       6
        1       1       0       2       3       4       5       6
        2       1       1       0       3       4       5       6
        3       2       1       1       0       4       5       6
        4       3       2       1       1       0       5       6
        5       4       3       2       1       1       0       6
        6       5       4       3       2       1       1       0
        6       5       4       3       2       1       1       0

最後,再次貼一下CSharpArray類的程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BasicStructure
{
    class CSharpArray
    {
        private int[] array;
        public CSharpArray(int count)
        {
            array = new int[count];
            Random random = new Random();
            for (int i = 0; i < count; i++)
            {
                array[i] = random.Next(count);
            }
        }
        public int[] getArray()
        {
            return array;
        }
        public void PrintArray(int []array)
        {
            int count=array.Length;
            for (int i = 0; i < count; i++)
            {
                Console.Write("\t{0}", array[i]);
                if ((i + 1) % 8 == 0)
                    Console.WriteLine();
            }
        }
        /// <summary>
        /// 氣泡排序演算法
        /// </summary>
        /// <param name="array">待排序的陣列</param>
        /// <param name="orderType">排序型別 0:升序;1:降序</param>
        public void BubbleSort(int []array,int orderType)
        {
            int temp;
            int count = array.Length;
            if(orderType==0)
            {
                for (int i = count; i >= 1; i--)
                {
                    for (int j = 0; j < i - 1; j++)
                    {
                        if (array[j] > array[j + 1])
                        {
                            temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                    PrintArray(array);
                }
            }else if(orderType==1)
            {
                for (int i = count; i >= 1; i--)
                {
                    for (int j = 0; j < i - 1; j++)
                    {
                        if (array[j] < array[j + 1])
                        {
                            temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                    PrintArray(array);
                }
            }
        }

        /// <summary>
        /// 插入排序演算法
        /// </summary>
        /// <param name="array">待排序的陣列</param>
        /// <param name="orderType">排序型別 0:升序;1:降序</param>
        public void InsertSort(int[] array,int orderType)
        {
            int j = 0,temp;
            int count = array.Length;
            if (orderType == 0)
            {
                for (int i = 1; i < count; i++)
                {
                    temp = array[i];
                    j = i;
                    while (j > 0 && array[j - 1] >= temp)
                    {
                        array[j] = array[j - 1];
                        j -= 1;
                    }
                    array[j] = temp;
                    PrintArray(array);
                }
            }
            else if (orderType == 1)
            {
                for (int i = 1; i < count; i++)
                {
                    temp = array[i];
                    j = i;
                    while (j > 0 && array[j - 1] <= temp)
                    {
                        array[j] = array[j - 1];
                        j -= 1;
                    }
                    array[j] = temp;
                    PrintArray(array);
                }
            }
        }

        /// <summary>
        /// 對半插入排序演算法
        /// </summary>
        /// <param name="array">待排序的陣列</param>
        /// <param name="orderType">排序型別 0:升序;1:降序</param>
        public void HalfInsertSort(int[] array, int orderType)
        {
            int j = 0, temp,low,high,mid;
            int count = array.Length;
            if (orderType == 0)
            {
                for (int i = 1; i < count; i++)
                {
                    temp = array[i];
                    low = 0;
                    high = i - 1;
                    while (low <= high)
                    {
                        mid = (low + high) / 2;
                        if (temp < array[mid]) high = mid - 1;
                        else low = mid + 1;
                    }
                    for (j = i - 1; j >= low; j--) array[j + 1] = array[j];
                    array[low] = temp;
                    PrintArray(array);
                }
            }
            else if (orderType == 1)
            {
                for (int i = 1; i < count; i++)
                {
                    temp = array[i];
                    low = 0;
                    high = i - 1;
                    while (low < high)
                    {
                        mid = (low + high) / 2;
                        if (temp > array[mid]) high = mid - 1;
                        else low = mid + 1;
                    }
                    for (j = i - 1; j >= low; j--) array[j + 1] = array[j];
                    array[low] = temp;
                    PrintArray(array);
                }
            }
        }
    }
}
OK,對半插入排序演算法的基本演示就到此結束!


注:由於陣列時程式碼裡生成的隨機陣列,因此每次執行的結果基本不一樣,可能與以上演示結果不同。


原創部落格 反饋請猛戳: