/// <summary>
        /// 选择排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="handle"></param>
        public static void Sort <T>(List <T> dataSources, SortCompareHandle <T> handle)
        {
            if (SortHelper.CheckParameter <T>(dataSources, handle) == false)
            {
                return;
            }

            int selectIndex = 0;

            for (int dex = 0; dex < dataSources.Count - 1; ++dex)   //注意这里dex<endIndex-1 因为 下面一个循环中会取下一个元素
            {
                selectIndex = dex;
                for (int j = dex + 1; j < dataSources.Count; ++j)
                {
                    if (handle(dataSources[selectIndex], dataSources[j]))
                    {
                        selectIndex = j;
                        //Debug.Log("Sort selectIndex=" + selectIndex);
                    }
                }
                if (dex != selectIndex)
                {
                    //    Debug.LogInfor("dex=" + dex + "    selectIndex=" + selectIndex);
                    SortHelper.Swap <T>(dataSources, dex, selectIndex);
                }
            }
        }
        /// <summary>
        /// 从第一个非叶子节点一直到根节点  比较根节点与左右两个子节点 如果满足条件就交换 然后调整交换后的子堆
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="i">当前比较的局部子树节点索引</param>
        /// <param name="size"></param>
        /// <param name="lessHandle"></param>
        private static void AdjustHeap <T>(List <T> dataSources, int i, int size, SortCompareHandle <T> lessHandle)
        {
            int lChild   = 2 * i + 1;      //左孩子
            int rChild   = 2 * i + 2;      //右孩子
            int maxIndex = i;              //临时变量 记录最大的节点的索引值

            if (i < size / 2)
            {                                                                                //如果i是叶子节点就结束
                if (lChild < size && lessHandle(dataSources[maxIndex], dataSources[lChild])) //dataSources[max] < dataSources[lChild])
                {
                    maxIndex = lChild;
                }
                if (rChild < size && lessHandle(dataSources[maxIndex], dataSources[rChild]))     //dataSources[max] < dataSources[rChild])
                {
                    maxIndex = rChild;
                }



                if (maxIndex != i)
                {
                    SortHelper.Swap <T>(dataSources, maxIndex, i);       //交换后破环了子树的堆结构
                    AdjustHeap(dataSources, maxIndex, size, lessHandle); //递归,调节子树为堆
                }
            }
        }
 //建立堆,堆是从下往上建立的,因为adjustHeap函数是建立在子树已经为大顶堆。
 private static void BuildHeap <T>(List <T> dataSource, int size, SortCompareHandle <T> lessHandle)
 {
     for (int i = size / 2; i >= 0; i--)
     {//从最后一个非叶子节点,才能构成adjustHeap操作的目标二叉树
         AdjustHeap(dataSource, i, size, lessHandle);
     }
 }
示例#4
0
        /// <summary>
        /// 检测参数是否合法 或者是否需要排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="handle"></param>
        /// <returns></returns>
        public static bool CheckParameter <T>(List <T> dataSources, SortCompareHandle <T> handle)
        {
            if (dataSources == null || dataSources.Count <= 1 || handle == null)
            {
                return(false);
            }

            return(true);
        }
 /// <summary>
 /// 归并排序
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="dataSources"></param>
 /// <param name="first"></param>
 /// <param name="last"></param>
 /// <param name="Handle"></param>
 /// <param name="temp">用于排序时候的临时分配数据 这里创建避免每次创建 (注意 temp必须是已经初始化的list 否则会报错)</param>
 public static void Sort <T>(List <T> dataSources, int first, int last, SortCompareHandle <T> Handle, List <T> temp)
 {
     if (first < last)
     {
         int mid = (first + last) / 2;
         //    Debug.Log("first=" + first + "   last" + last + "   mid=" + mid);
         Sort(dataSources, first, mid, Handle, temp);                 //左边有序
         Sort(dataSources, mid + 1, last, Handle, temp);              //右边有序
         mergearray <T>(dataSources, first, mid, last, Handle, temp); //再将二个有序数列合并
     }
 }
        /// <summary>
        /// 插入排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="handle"></param>
        public static void Sort <T>(List <T> dataSources, SortCompareHandle <T> handle)
        {
            if (SortHelper.CheckParameter <T>(dataSources, handle) == false)
            {
                return;
            }

            for (int i = 1; i < dataSources.Count; i++)
            {
                for (int j = i - 1; j >= 0 && handle(dataSources[j], dataSources[j + 1]); j--)
                {
                    SortHelper.Swap <T>(dataSources, j, j + 1);
                }
            }
        }
        //将数组分为两部分,一部分为有序区,在数组末尾,另一部分为无序区。堆属于无序区

        /// <summary>
        /// 堆排序 排序后的结果是一个从小到大的结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="lessHandle">比较两个数据小于的比较方法</param>
        public static void Sort <T>(List <T> dataSources, SortCompareHandle <T> lessHandle)
        {
            BuildHeap(dataSources, dataSources.Count, lessHandle);  //首先建立基本的堆结构

            //for (int dex = 0; dex < dataSources.Count; ++dex)
            //{
            //    Debug.Log(dataSources[dex]);
            //}

            for (int i = dataSources.Count - 1; i > 0; i--)
            {                                              //i为无序区的长度,经过如下两步,长度递减
             //堆顶即下标为0的元素
                SortHelper.Swap <T>(dataSources, i, 0);    //1.每次将堆顶元素和无序区最后一个元素交换,即将无序区最大的元素放入有序区
                AdjustHeap(dataSources, 0, i, lessHandle); //2.将无顺区调整为大顶堆,即选择出最大的元素。
            }
        }
        /// <summary>
        /// 简单的冒泡排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="handle"></param>
        public static void Sort <T>(List <T> dataSources, SortCompareHandle <T> handle)
        {
            if (SortHelper.CheckParameter <T>(dataSources, handle) == false)
            {
                return;
            }

            int count = 0;  //已经完成的排序次数

            for (int dex = 0; dex < dataSources.Count; ++dex)
            {
                for (int j = 0; j < dataSources.Count - count - 1; ++j)
                {
                    if (handle(dataSources[j], dataSources[j + 1]))
                    {
                        SortHelper.Swap <T>(dataSources, j, j + 1);
                    }
                }
                ++count;
            }
        }
示例#9
0
        public static void Sort <T>(List <T> dataSources, SortCompareHandle <T> handle)
        {
            if (SortHelper.CheckParameter <T>(dataSources, handle) == false)
            {
                return;
            }

            int[] sedgewick = Sedgewick(dataSources.Count);// 得到塞奇威克(Sedgewick) 步长序列数组

            for (int dex = 0; dex < sedgewick.Length; ++dex)
            {
                Debug.Log(sedgewick[dex]);
            }

            int s, k, i, j;
            T   t;

            // 循环出所有步长
            for (s = sedgewick.Length - 1; s >= 0; s--)
            {
                // 步长为sedgewick[s] 即分为 sedgewick[s] 个组
                for (k = 0; k < sedgewick[s]; k++)
                {
                    // 对每组数据进行排序
                    for (i = k + sedgewick[s]; i < dataSources.Count; i += sedgewick[s])
                    {
                        // 分组中,按插入排序排序数据,交换数据按步长 sedgewick[s]
                        t = dataSources[i];
                        j = i - sedgewick[s];
                        while (j >= 0 && handle(dataSources[j], t))       //dataSources[j] > t)
                        {
                            dataSources[j + sedgewick[s]] = dataSources[j];
                            j -= sedgewick[s];
                        }
                        dataSources[j + sedgewick[s]] = t;
                    }
                }
            }
        }
        /// <summary>
        /// 将有二个有序数列a[first...mid]和a[mid...last]合并。
        /// 思路:依次取出两个List的第一个元素比较大小,取出最大或者最小一个元素保存到临时列表中。当有一个list数据取完时候另一个List数据直接全部加在临时数据后面即可
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="first"></param>
        /// <param name="mid"></param>
        /// <param name="last"></param>
        /// <param name="handle"></param>
        /// <param name="temp"></param>
        private static void mergearray <T>(List <T> dataSources, int first, int mid, int last, SortCompareHandle <T> handle, List <T> temp)
        {
            int i = first;
            int j = mid + 1;
            int m = mid;
            int n = last;
            int k = 0;  //记录一共有多少数据被保存到临时List中

            while (i <= m && j <= n)
            {
                if (handle(dataSources[i], dataSources[j]))
                {
                    temp[k++] = dataSources[i++];
                }
                else
                {
                    temp[k++] = dataSources[j++];
                }
            }//当两个List中数据都没有取完时候

            while (i <= m)
            {
                temp[k++] = dataSources[i++];
            }

            while (j <= n)
            {
                temp[k++] = dataSources[j++];
            }

            for (i = 0; i < k; i++)
            {
                dataSources[first + i] = temp[i];
            }
        }
        /// <summary>
        /// 数据分组 返回值时下一次排序时候中间轴的位置索引
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSources"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="ratherEqualHandle"></param>
        /// <param name="lessEqualHandle"></param>
        /// <returns></returns>
        private static int Partition <T>(List <T> dataSources, int startIndex, int endIndex, SortCompareHandle <T> ratherEqualHandle, SortCompareHandle <T> lessEqualHandle)
        {
            int pivotIndex = startIndex;
            T   pivot      = dataSources[startIndex]; //枢轴记录
            int leftPoint  = 0;                       //记录左侧比轴数据小的数据索引
            int rightPoint = 0;                       //记录右 侧比轴数据大的数据索引

            //****思路: 先从当前子数组的末尾开始找到第一个小于轴数据并记录索引值,然后从左往右找到第一个比轴数据大的元素索引,然后交换两个记录索引对应的数据,继续查找 ,直到左右两个索引相同时候与轴数据交换
            while (startIndex < endIndex)
            {
                while (startIndex < endIndex && ratherEqualHandle(dataSources[endIndex], pivot))                // dataSources[endIndex] >= pivot)
                {
                    --endIndex;
                }
                rightPoint = endIndex;                                                           //小于轴数据并记录索引值
                while (startIndex < endIndex && lessEqualHandle(dataSources[startIndex], pivot)) //dataSources[startIndex] <= pivot)
                {
                    ++startIndex;
                }
                leftPoint = startIndex;                                  //大于轴数据并记录索引值

                SortHelper.Swap <T>(dataSources, leftPoint, rightPoint); //交换两个记录数据
            }
            SortHelper.Swap <T>(dataSources, pivotIndex, startIndex);    //当前这次已经找到轴的位置
            //返回的是枢轴的位置
            return(startIndex);
        }
 /// <summary>
 ///  简单的快速排序
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="dataSources">需要排序的数据源</param>
 /// <param name="startIndex">排序的起始索引</param>
 /// <param name="endIndex">排序的结束索引</param>
 /// <param name="ratherEqualHandle">泛型化判断是否是大于等于    </param>
 /// <param name="lessEqualHandle">泛型化判断是否是小于等于    </param>
 public static void Sort <T>(List <T> dataSources, int startIndex, int endIndex, SortCompareHandle <T> ratherEqualHandle, SortCompareHandle <T> lessEqualHandle)
 {
     if (startIndex < endIndex)
     {
         int pivot = Partition <T>(dataSources, startIndex, endIndex, ratherEqualHandle, lessEqualHandle); //将数组分为两部分
         Sort <T>(dataSources, startIndex, pivot - 1, ratherEqualHandle, lessEqualHandle);                 //递归排序左子数组
         Sort <T>(dataSources, pivot + 1, endIndex, ratherEqualHandle, lessEqualHandle);                   //递归排序右子数组
     }
 }