zoukankan      html  css  js  c++  java
  • 快速排序及其优化

    package com.zc.algorithm;

    public class QuickSort {
        //快速排序:挖坑法
        public int partition(int[] arr, int left, int right)
        {
            if(left<right)
            {
                int temp = arr[left];
                while(left<right)
                {
                    //如果右边的数大于基数temp,则向左移动
                    while(left<right&&arr[right] >= temp)
                    {
                        right--;
                    }
                    //如果不大于,则把右边的数赋值给左边
                    arr[left] = arr[right];
                    //如果左边的数小于基数,则向右移动
                    while(left<right&&arr[left] <= temp)
                    {
                        left++;
                    }
                    //如果左边的数大于基数,则左边的数赋值给右边
                    arr[right] = arr[left];
                }
                arr[left]=temp;
            }
            
            return left;
        }
     public int[] QSort(int[] arr, int left, int right)
     {
         int[] newArr = arr;
         if(left < right)
         {
         int pivot = partition(newArr, left, right);
         QSort(newArr,left,pivot-1);
         QSort(newArr, pivot+1,right);
         }
         return newArr;
     }
     //快速排序优化1:三数取中法,将数组中的开头、结尾和中间的数做比较,把最大的放在末尾,然后把最小的放在中间,第二大的放在开头,解决数组中部分有序的问题
     public void MedianOfThree(int[] arr, int left, int right)
     {
         int mid = left+(left+right);
         if(arr[left] > arr[right])//把最大值放在数组的末尾
         {
             swap(arr, left, right);
         }
         if(arr[mid]> arr[right])//把最大值放在数组的末尾
         {
             swap(arr, mid, right);
         }
         if(arr[mid]>arr[left])//把最小值放在中间
         {
             swap(arr, mid, left);
         }
     }
     //交换
     public void swap(int[] arr, int left, int right)
     {
             int temp = arr[left];
             arr[left] = arr[right];
             arr[right] = temp;
     }
     public int[] QSort_MedianOfThree(int[] arr, int left, int right)
     {
         //[1]先进行数字调换
         MedianOfThree(arr,left,right);//将中间数放到开头
         int[] newArr = arr;
         if(left < right)
         {
         int pivot = partition(newArr, left,right);
         QSort(newArr,left,pivot-1);
         QSort(newArr, pivot+1,right);
         }
         return newArr;
     }
     //快速排序优化2:三数取中+插入排序
     public int[] insertSort(int[] arr)
     {
         int j = 0;
         for(int i = 1; i< arr.length; i++)
         {
             int temp = arr[i];
             for( j = i-1; j >=0&&arr[j]>temp;j--)
             {
                 arr[j+1] = arr[j];
             }
             arr[j+1] = temp;
         }
         return arr;
     }
     public int[] QSort_Insert(int[] arr, int left, int right)
     {
         //如果数组的长度小于10,则采用插入排序
         if(right - left +1 < 10)
         {
             return insertSort(arr);
         }
         //[1]先进行数字调换
         MedianOfThree(arr,left,right);//将中间数放到开头
         int[] newArr = arr;
         if(left < right)
         {
         int pivot = partition(newArr, left,right);
         QSort(newArr,left,pivot-1);
         QSort(newArr, pivot+1,right);
         }
         return newArr;
     }
     
      //快速排序优化3:三数取中+插排+聚集相同元素,解决数组中部分重复的问题
     public int[] QsortThreeInsertGather(int[] arr, int low, int high)
     {
         if(high - low+1<10)
         {
             return insertSort(arr);
         }
         //三数取中
         MedianOfThree(arr, low, high);
         int first = low;
         int last = high;
         int left = low;
         int right = high;
         int leftLength = 0;
         int rightLength = 0;
         int key = arr[first];
         while(first < last)
         {
             while(first < last&&arr[last]>=key)
             {
                 if(arr[last] == key)
                 {
                     swap(arr, last, right);
                     right--;
                     rightLength++;
                 }
                 last--;
             }
             arr[first] = arr[last];
             while(first<last&& arr[first]<=key)
             {
                 if(arr[first] == key)
                 {
                     swap(arr, first,left);
                     left++;
                     leftLength++;
                 }
                 first++;
             }
             arr[first] = key;
         }
        int i = first - 1;
        int j =low;
        while(j < left&&arr[i]!=key)
        {
            swap(arr,i,j);
            i--;
            j++;
        }
        i =last+1;
        j = high;
        while(j>right&&arr[i]!=key)
        {
            swap(arr,i,j);
            i++;
            j--;
        }
        QsortThreeInsertGather(arr,low,first-leftLength-1);
        QsortThreeInsertGather(arr,first+rightLength+1,high);
        return arr;
     }
    }

  • 相关阅读:
    iter方法读取文件的例子
    Python的datetime与Decimal数据进行json序列化的简单说明
    路由分发时名称空间的2种写法
    “投票练习”笔记
    基于DRF的图书增删改查练习
    【转】很实用的编程英语词库,共收录一千五百余条词汇
    Django的media配置与富文本编辑器使用的实例
    利用Git版本控制管理你的项目
    docker学习与应用
    SharePoint 2010 以Jquery Ajax方式更新SharePoint列表数据!
  • 原文地址:https://www.cnblogs.com/zhangchuan1001/p/10725782.html
Copyright © 2011-2022 走看看