zoukankan      html  css  js  c++  java
  • 面试排序算法总结

    冒泡排序

      冒泡排序是最基础的排序算法了,大体的思想是通过与相邻元素的比较和交换把小的数交换到最前面。不断的重复交换的过程,直到有一轮遍历没有发生交换。冒泡排序的时间复杂度为$O(n^{2})$。

      代码如下:

    class BubbleSort
    {
    public:
        void bubbleSort(vector<int>& arr)
        {
            if(arr == null || arr.length == 0)
                return ;
            for(int i=0; i<arr.size()-1; i++)
            {
                int flag = 0;       
                for(int j=arr.size()-1; j>i; j--)
                {
                    if(arr[j] < arr[j-1])
                    {
                        swap(arr, j-1, j);
                        flag = 1;
                    }
                }
                if(flag == 0) break;
            }
        }
    
        void swap(vector<int>& arr, int i, int j)
        {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    选择排序

      大致思想和冒泡一致,一次排序之后把最小的值放在最前面,但是过程不同。选择排序一次遍历的时候找到除了起始位置之外最小的值,然后考虑是否与其实位置的值交换。时间复杂度为$O(n^{2})$。代码如下:

      

    class SelectSort
    {
    
    public:
        void selectSort(vector<int>& arr)
        {
            if(arr == null || arr.size() == 0)
                return ;
            int minIndex = 0;
            for(int i=0; i<arr.size()-1; i++)   //只需要比较n-1次
            {
                minIndex = i;
                for(int j=i+1; j<arr.size(); j++)   //从i+1开始比较,因为minIndex默认为i了,i就没必要比了。
                {
                    if(arr[j] < arr[minIndex])
                    {
                        minIndex = j;
                    }
                }
                if(minIndex != i)   //如果minIndex不为i,说明找到了更小的值,交换之。
                {
                    swap(arr, i, minIndex);
                }
            }
    
        }
        void swap(vector<int>& arr, int i, int j)
        {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
    }

    插入排序:

      依次枚举数组的每个index,在枚举的时候保证index之前的数是有序的。在枚举到i的时候,有序的插入到[0,i-1]子数组中,重复上述步骤即可。代码如下:

      

    void insertSort(vector<int>& arr)
        {
            if(arr == null || arr.size() == 0)
                return ;
    
            for(int i=1; i<arr.size(); i++)   //假设第一个数位置时正确的;要往后移,必须要假设第一个。
            {
    
                int j = i;
                int target = arr[i]; //待插入的
    
                //后移
                while(j > 0 && target < arr[j-1])
                {
                    arr[j] = arr[j-1];
                    j --;
                }
    
                //插入
                arr[j] = target;
            }
    
        }

    快速排序:

      快速排序可以理解为冒泡排序的一个改进,冒泡排序是通过相邻元素的比较和交换把最小的冒泡到最顶端,而快速排序是比较和交换小数和大数,这样一来不仅把小数冒泡到上面同时也把大数沉到下面。

      举个栗子:对$5,3,8,6,4$这个无序序列进行快速排序,思路是右指针找比基准数小的,左指针找比基准数大的,交换之。

      $5,3,8,6,4$ 用5作为比较的基准,最终会把5小的移动到5的左边,比5大的移动到5的右边。

      $5,3,8,6,4$首先设置$i,j$两个指针分别指向两端,$j$指针先扫描4比5小停止。然后$i$扫描,8比5大停止。交换$i,j$位置。

      $5,3,4,6,8$然后$i$指针再扫描,这时j扫描4时两指针相遇。停止。然后交换4和基准数。

      $4,3,5,6,8$ 一次划分后达到了左边比5小,右边比5大的目的。之后对左右子序列递归排序,最终得到有序序列。

      

    int Partition(vector<int>& arr,int left,int right)
    {
       int tmp = arr[left];
       while(left < right)
       {
           while(left < right && arr[right] >= tmp) right--;
           arr[left] = arr[right];
           while(left < right && arr[left] <= tmp) left++;
           arr[right] = arr[left];
       }
       arr[left] = tmp;
       return left;
    }
    
    void quickSort(vector<int>& arr, int left, int right)
    {
        if(left >= right)
            return ;
        int pivotPos = Partition(arr, left, right);
        quickSort(arr, left, pivotPos-1);
        quickSort(arr, pivotPos+1, right);
    }

    堆排序:

      简单说一下堆排序的基本思路:

      a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

      b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

      c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

      简单说明一下如何条件结构,首先找到最后一个非叶子节点(这里用数组模拟树的化,第一个非叶子节点为arr.size()-1),从左至右,从上到下调整。例如对于初始的状态:

      

       我们从index = 1的节点开始调整:

      这时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6。

       这样一个大根堆就调整好了。之后不断的将末尾的数换至数组起始位置进行调整就好了,代码如下:

    class HeapSort
    {
    
        publicvoid Sort(vector<int>& arr)
        {
            //1.构建大顶堆
            for(int i=arr.size()/2-1; i>=0; i--)
            {
                //从第一个非叶子结点从下至上,从右至左调整结构
                adjustHeap(arr,i,arr.size());
            }
            //2.调整堆结构+交换堆顶元素与末尾元素
            for(int j=arr.size()-1; j>0; j--)
            {
                swap(arr,0,j);//将堆顶元素与末尾元素进行交换
                adjustHeap(arr,0,j);//重新对堆进行调整
            }
    
        }
    
        /**
         * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
         * @param arr
         * @param i
         * @param length
         */
        void adjustHeap(vector<int>& arr,int i,int length)
        {
            int temp = arr[i];//先取出当前元素i
            for(int k=i*2+1; k<length; k=k*2+1) //从i结点的左子结点开始,也就是2i+1处开始 不断的向下调整
            {
                if(k+1<length && arr[k]<arr[k+1]) //如果左子结点小于右子结点,k指向右子结点
                {
                    k++;
                }
                if(arr[k] >temp) //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                {
                    arr[i] = arr[k];
                    i = k;
                }
                else
                {
                    break;
                }
            }
            arr[i] = temp;//将temp值放到最终的位置
        }
    
        /**
         * 交换元素
         * @param arr
         * @param a
         * @param b
         */
        void swap(int []arr,int a,int b)
        {
            int temp=arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
    }

    希尔排序:

    (待整理)  

    归并排序:

      

    https://www.cnblogs.com/wxisme/p/5243631.html

      

  • 相关阅读:
    Android应用开发学习笔记之事件处理
    [置顶] 炎炎夏日,给你一次极爽的开发体验!——统一开发环境功能升级优化,正式上线V2.0!
    POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
    京东商城发现了一枚Bug
    iOS_40_核心动画
    SVN——库合并
    ORACLE 8i 遇到报错:ORA-01631: max # extents (505) reached in table
    HDU 5366:The mook jong 递推
    Linux平台下裸设备的绑定:
    CSP:使用CryptoAPI解码X509证书内容
  • 原文地址:https://www.cnblogs.com/z1141000271/p/12771479.html
Copyright © 2011-2022 走看看