排序

1. 在多个数据元素(Ri)的序列,其中每个元素有相应的关键字(Ki)(也叫元素的属性),通过关键字的固有关系来对对应数据元素进行排序

2. 排序稳定性:元素R1 R2 的关键字K1 K2相同,排序前R1在R2前面,排序后 R1在R2前面,则该排序方法是稳定的。

3. 多关键字排序:排序先用最高优先级的关键字N1进行排序,,当N1关键字相同时使用N2优先级关键字进行排序,如果关键字还是相同依次使用N2,,Nn-1

4. 排序和交换两个重要手段

5. 排序选择要素:时间性能,空间性能,程序复杂度

 

1.选择排序

  思想:在排序到当前序列第 i 和元素时,从后面 n-i 个元素中选出最小元素,作为当前排序序列第 i 个元素。 

       

 

 

  code:

        static void select(T array[], int len)
        {
            for(int x = 0; x < len; x++)
            {
                int min = x; 
                for(int y = x + 1; y < len; y++)
                {
                    if(array[min] > array[y]) //升序< 降序>
                        min = y;
                }
                if(min != x)
                    swap(array[x],array[min]); //不稳定排序
            }

 

  

2.插入排序

  思想:序列分为有序序列和无需序列。未排序序列选择第 i (1) 位的元素时,插入到前面的有序序列,使用 i 元素的关键字与前 i-1 个元素关键字进行比较,找到位置后插入即可   

        

 

 

        template <typename T>
        static void insert_sort(T array[], int len, bool ascend = false)
        {
            for(int x = 1; x < len; x++)
            {
                int z = x;
                T temp = array[z];
                for(int y = x - 1; (y >= 0) && (ascend ? array[y] > temp: array[y] < temp); y--)
                {
                    array[y + 1] = array[y]; //稳定排序
                    z = y;
                }
                if(z != x)
                {
                    array[z] = temp;
                }
            }
        }

 

 

3.冒泡排序

  思想:序列分为有序序列和无序序列,从整个序列的最后一个元素开始向前依次比较大小,小则比较数前移,大则用被比较的元素前移。

        

 

 

template <typename T>
        static void bubble_sort(T array[], int len, bool ascend = false)
        {
            bool state = ture;
            for(int x = 0; x < len && state; x++) //某个元素无法前的元素都是有序的,表明有序
            {
                state = false;
                for(int y = len - 1; y > x; y--)
                {
                    if(ascend ? array[y] > array[y - 1] : array[y] < array[y - 1])
                    {
                        swap(array[y],array[y - 1]);
                        state = ture; 
                    }
                }
            }
        }

 

 

4.希尔排序

  思想:将n个元素的序列分为d组,每一组使用插入排序。然后再分为d-1组,再分别排序。直到d=1。

  如何分组: 将n个元素分为d个子序列:第一组:{R[1],R[1+d],R[1+2d]...R[1+kd]} 第二组:{R[2],R[2+d],R[2+2d]....R[2+kd]} .........第d组:{R[d],R[2d],R[3d]...R[(1+k)d]} 。

        

 

 

        template <typename T>
        static void shell_sort(T array[], int len, bool ascend = false)
        {
            int d = len;
            do
            {
                d = d / 3 + 1; //???
                for(int x = d ; x < len; x += d)
                {
                    int z = x;
                    T temp = array[z];
                    for(int y = x - d; (y >= 0) && (ascend ? array[y] > temp: array[y] < temp); y -= d)
                    {
                        array[y + d] = array[y]; //稳定排序
                        z = y;
                    }
                    if(z != x)
                    {
                        array[z] = temp;
                    }
                }
            }
            while(d > 1);
        }

 

 

 

5.归并排序

  思想:先将一个无序序列划分为两个无序序列,再将两个无序序列接着向下划分,直到每个子序列只包含一个元素此时每个子序列都是有序序列,

                 再两个两个子序列比较后合并,直到所有子序列合并为原来的序列,此时序列变为有序。

     几个有序序列归并就叫几路归并。

            稳定但是花费空间

                 

 

 

    template <typename T>
        static void merge_sort(T array[], int len, bool ascned = ture)
        {
            T* temp_array = new T[len];
            merge_sort_core(array, temp_array, 0, len - 1, ture);
            delete[] temp_array;
        }

        template <typename T>
        static void merge_sort_core(T array[], T temp_array[], int begin, int end, bool ascned = ture)
        {
            if(begin == end)
            {
                return;
            }
            else
            {
          // 分割
int mid = (begin + end) / 2; merge_sort_core(array, temp_array, begin, mid, ascned); merge_sort_core(array, temp_array, mid + 1, end, ascned); // 合并 int x = begin, y = mid + 1, z = begin; while(x <= mid && y <= end) { if(array[x] < array[y]) { temp_array[z++] = array[x++]; } else { temp_array[z++] = array[y++]; } } while(x <= mid) { temp_array[z++] = array[x++]; } while(y <= end) { temp_array[z++] = array[y++]; } for(z = begin; z <= end; z++) { array[z] = temp_array[z]; } } }

 

 

6.快速排序

 思想: 通过在序列中选择一个基准值对一个无序序列划分,将无序序列大于基准值的放在左边,小于基准值的放在右边。再把左右两个子序列继续寻找基准值继续划分下去。

    最后每个序列都只有一个元素,而此时整个序列变成有序的。

               不稳定但是花费空间

               

 

 

        template <typename T>
        static void quick_sort(T array[], int len, bool ascned = ture)
        {
            quick_sort_core(array, 0, len - 1, ascned);
        }

        template <typename T>
        static void quick_sort_core(T array[], int begin, int end, bool ascned = ture)
        {
            //确定基准值的位置
            int base_pos = 0, base_value = array[begin], begin_slide = begin, end_slide = end;
            while(begin_slide < end_slide)
            {
                while(begin_slide < end_slide && ascned ? base_value  < array[end_slide] : base_value  > array[end_slide])
                {
                    --end_slide;
                }
                swap(array[begin_slide], array[end_slide]);
                while(begin_slide < end_slide && ascned ? base_value >= array[begin_slide] : base_value <= array[begin_slide])
                {
                    ++begin_slide;
                }
                swap(array[begin_slide], array[end_slide]);
            }
            array[begin_slide] = base_value;
            base_pos = begin_slide;
            //继续划分
            quick_sort_core(array, begin, (base_pos - 1), ascned);
            quick_sort_core(array, base_pos + 1, end, ascned);
        }

 

posted @ 2020-02-29 19:07  张不源  Views(254)  Comments(0Edit  收藏  举报