zoukankan      html  css  js  c++  java
  • 经典算法之七大排序

    【交换排序】:冒泡排序,快速排序 【选择排序】:简单选择排序,堆排序

    【插入排序】:简单插入排序,希尔排序 ;归并排序

    一:交换排序

     public class BubbleSort
        {
            public static List<int> Sort(List<int> list)
            {
                int temp = 0;
                //要比较的次数 n-1
                for (int i = 0; i < list.Count - 1; i++)
                {   
                    //从底部开始
                    for (int j = list.Count - 1; j > i; j--)
                    {   
                        //往下沉
                        if (list[j - 1]>list[j])
                        {
                            temp = list[j];
                            list[j] = list[j - 1];
                            list[j - 1] = temp;
                        }
                    }
                }
                return list;
            }
        }
    

     快排

     1  public class QuickSort
     2     {
     3         public static void Sort(List<int> list,int left,int right)
     4         {
     5             if (left < right)
     6             {
     7                 int i = Division(list, left, right);
     8                 Sort(list, left, i - 1);
     9                 Sort(list,i+1,right);
    10             }
    11         }
    12 
    13         private static int Division(List<int> list, int left, int right)
    14         {   
    15             //挑选基准元素
    16             int baseNum = list[left];
    17 
    18             while (left < right)
    19             {   
    20                 //从数组的右端开始向前找,一直找到比base小的数字为止
    21                 while (left < right && list[right] >= baseNum)
    22                 {
    23                     right = right - 1;
    24                 }
    25                 list[left] = list[right];
    26 
    27                 while (left < right && list[left] <= baseNum)
    28                 {
    29                     left = left + 1;
    30                 }
    31                 list[right] = list[left];
    32             }
    33 
    34             list[left] = baseNum;
    35             
    36             return left;
    37         }

    二:选择排序:

     1  public class SelectionSort
     2     {
     3         static void Sort(List<int> list)
     4         {
     5             for (int i = 0; i < list.Count - 1; i++)
     6             {   
     7                 //设置tempIndex的下标值
     8                 int tempIndex = i;
     9                 for (int j = i + 1; j < list.Count; j++)
    10                 {
    11                     if (list[tempIndex] > list[j])
    12                     {
    13                         tempIndex = j;
    14                     }
    15                 }
    16 
    17                 var tempData = list[tempIndex];
    18                 list[tempIndex] = list[i];
    19                 list[i] = tempData;
    20             }
    21         }
    /// <summary>
        /// 堆排序(大根堆,小根堆)
        /// 大根堆(父结点比孩子结点都要大)
        /// 小跟堆(父结点比孩子结点都要小)
        /// </summary>
        public class HeapSort
        {
            public static void Sort(List<int> list)
            {   
                //list.Count/2-1:就是堆中父节点的个数
                for (int i = list.Count / 2 - 1; i >= 0; i--)
                {
                    HeapAdjust(list, i, list.Count);
                }
    
                //最后输出堆
                for (int i = list.Count - 1; i > 0; i--)
                {   
                    //堆顶与当前堆的第i个元素值对调,将对顶踢出,破换堆
                    int temp = list[0];
                    list[0] = list[i];
                    list[i] = temp;
    
                    //因为两值交换,可能破坏根堆,所以必须重新构造
                    HeapAdjust(list, 0, i);
                }
    
            }
    
            private static void HeapAdjust(List<int> list, int parent, int length)
            {   
                //temp保留当前父结点
                int temp = list[parent];
                
                //得到左孩子(二叉树的定义)
                int child = 2 * parent + 1;
    
                while (child < length)
                {   
                    //如果parent有右孩子,则判断左孩子是否小于右孩子
                    if (child + 1 < length && list[child] < list[child + 1])
                        child++;
    
                    if (temp > list[child])
                        break;
    
                    //将较大结点的值赋给父结点
                    list[parent] = list[child];
    
                    //然后将子节点做为父亲节点,已防止是否破坏根堆时重新构造
                    parent = child;
    
                    //找到该父亲节点较小的左孩子节点
                    child = 2 * parent + 1;
                }
                //最后将temp值赋给较大的子结点,形成两值交换
                list[parent] = temp;
            }
    
        
        }

    三:插入排序

      /// <summary>
        /// 插入排序
        /// </summary>
        /// <remarks>
        /// 数组被划分为无序数组块和有序数组块
        /// </remarks>
        public class InsertSort
        {
            static void Sort(List<int> list)
            { 
                //无序序列
                for (int i = 1; i < list.Count; i++)
                {
                    var temp = list[i];
                    int j;
    
                    //有序序列
                    for (j = i - 1; j >= 0 && temp < list[j]; j--)
                    {
                        list[j + 1] = list[j];
                    }
                    list[j + 1] = temp;
    
                }
            }
        }
     public class ShellSort
        {
            static void Sort(List<int> list)
            {   
                //取增量
                int step = list.Count/ 2;
    
                while (step >= 1)
                {
                    for (int i = step; i < list.Count; i++)
                    {
                        int temp = list[i];
                        int j;
                        for (j = i - step; j >= 0 && temp < list[j]; j = j - step)
                        {
                            list[j + step] = list[j];
                        }
                        list[j + step] = temp;
                    }
                    step = step / 2;
                }
            }
        }

    四:归并排序

      /// <summary>
        /// 归并排序的过程
        /// 第一: “分”,  就是将数组尽可能的分,一直分到原子级别。
        ///第二: “并”,将原子级别的数两两合并排序,最后产生结果。
        /// </summary>
        public class MergeSort
        {
            static void Sort(int[] array, int[] temparray, int left, int right)
            {
                if (left < right)
                { 
                    //取分割位置
                    int middle = (left + right) / 2;
    
                    //先递
                    Sort(array, temparray, left, middle);
    
                    Sort(array, temparray, middle + 1, right);
    
                    //后归
                    Merge(array, temparray, left, middle + 1, right);
                }
            }
    
            //数组的两两合并操作
            private static void Merge(int[] array, int[] temparray, int left, int middle, int right)
            {
                //左指针尾
                int leftEnd = middle - 1;
                //右指针头
                int rightStart = middle;
    
                //临时数组的下标
                int tempIndex = left;
    
                //数组合并后的length长度
                int tempLength = right - left + 1;
    
                //先循环两个区间都没有结束的情况
                while ((left <= leftEnd) && (rightStart <= right))
                {
                    if (array[left] < array[rightStart])
                    {
                        temparray[tempIndex++] = array[left++];
                    }
                    else
                    {
                        temparray[tempIndex++] = array[rightStart++];
                    }
                }
    
                //判断左序列是否结束
                while (left <= leftEnd)
                    temparray[tempIndex++] = array[left++];
    
                while (rightStart <= right)
                    temparray[tempIndex++] = array[rightStart++];
    
                //交换数据
                for (int i = 0; i < tempLength; i++)
                {
                    array[right] = temparray[right];
                    right--;
                }
    
            }
        }
  • 相关阅读:
    函数式组件中的class与style处理
    学习CSS(二)
    mysql优化二
    mysql优化一
    spring解决循环依赖
    Java多线程2:Thread中的实例方法
    当try、catch中有return时,finally中的代码会执行么?
    Java多线程1:进程与线程
    手写springmvc
    手写spring
  • 原文地址:https://www.cnblogs.com/binfire/p/2865863.html
Copyright © 2011-2022 走看看