C++实现主要排序算法

912题为例,

1 堆排序,堆的结构是:节点i的孩子是2*i和2*i,n/2-1, n/2-2, ...1这些父节点选择元素时,有可能n/2-2父节点交换将元素a交换过去了,而n/2-1父节点没将孩子里也是a的值交换,故不稳定;

2 插入排序,在已有有序序列插入一个元素,如果遇见一个与插入元素相等的,那么把待插入的元素放在相等元素的后面,故相等元素的前后顺序没有改变,稳定;

3 希尔排序,间隔d内单次是一个插入排序,d距离直到1才完成排序,但是不同距离排序过程中,相同元素可能在各自插入排序中打乱,故不稳定;

4 选择排序,多趟,每趟选出最小的放入有序序列最后a[i]。某一趟如果选出的最小值涉及到与最后a[i]的交换,若最小值之前仍有a[i]一样的值,则交换后,两个一样值的a[i]顺序就不保证,故不稳定;

5 冒泡排序,多趟,每趟相邻两两交换,冒泡出最大值到数组最后,相同元素不会交换,故稳定;

6 快速排序,选出基准p,划分左右两个区间,i/j前后便利后最终i==j,此时就是两个区间分界,将基准与分界a[i]交换,此时有可能就改变顺序,故不稳定;

class Solution {
public:
    vector sortArray(vector& nums) {
        // solve 1.1 headSort by hand
        // heapSort(nums);
        // solve 1.2 headSort by c++'s algorithms
        // make_heap(nums.begin(),nums.end());// default is big heap
        // sort_heap(nums.begin(),nums.end());
        // solve 2 insert sort, may be time out
        // insertSort(nums);
        // solve 3 shell sort
        // shellSort(nums);
        // solve 4 select sort
        //selectSort(nums);
        // solve 5 swap sort
        // swapSort(nums);
        // solve 6 quick sort
        quickSort(nums);
        return nums;
    }
private:
    // 1 堆排序
    void constructHeap(vector&nums){
        // 从最后一个非叶子节点len/2-1开始调整,从下到上
        for(int i=nums.size()/2-1;i>=0;i--){
            adjustHeap(nums,i,nums.size());
        }
    }
    void adjustHeap(vector&nums,int start,int end){
        // 每次调整使得满足堆定义
        int child;
        int i=start;
        while(1){
            child=2*i+1;
            if(child>end-1){
                break;
            }
            if(child+1<=end-1&&nums[child]&nums){
        // 构建大顶堆
        constructHeap(nums);
        // 把根节点跟最后一个元素交换位置,调整剩下的n-1个节点,即可排好序
        for(int i=nums.size()-1;i>=0;i--){
            swap(nums[0],nums[i]);
            adjustHeap(nums,0,i);
        }
    }
    // 2 插入排序。在已排序的序列基础上从未排序序列选出一个插入排序序列
    // 一直往前找直到找到它该插入的位置。如果遇见一个与插入元素相等的,那么把待插入的元素放在相等元素的后面。因此是稳定排序
    void insertSort(vector&nums){
        int n=nums.size();
        int i,j;
        for(i=1;i=0&&nums[j]>tmp){
                //a[j]>tmp 比较大 往后挪,给待插入值腾位置
                nums[j+1]=nums[j];
                j--;
            }
            nums[j+1]=tmp;
        }
    }
    // 3 shell排序,升级版插入排序,核心是选择一个增量d(如原始数组的一半),对相距d距离的所有元素进行插入排序,完成一次排序后只是说明间隔d的元素有序,缩小增量d,直至d=1才说明完全有序
    // 在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,故不稳定
    void shellSort(vector&nums){
        int n=nums.size();
        int d=n/2;
        int i,j;
        while(d>0){
            //对相距d距离的所有元素进行插入排序
            for(i=d;i=0&&nums[j]>tmp){
                    nums[j+d]=nums[j];
                    j-=d;
                }
                nums[j+d]=tmp;
            }
            d=d/2;
        }
    }
    // 4 选择排序,a[0]...a[i-1]是已排序数组,从a[i]...a[n-1]未排序中选出最小值作为a[i],直接放在数组a[0]-a[i-1]最后位置
    // 在一趟选择中,当前元素a1比后面元素b要大,且当前元素一样的值a2也出现在了b的前面,那样交换位置后a1/a2位置也交换了所以不稳定
    void selectSort(vector&nums){
        int n=nums.size();
        int i,j;
        //n-1轮排序,每一轮选出一个最小值,最后一个元素就是最大值故不需要n轮
        for(i=0;i&nums){
        int n=nums.size();
        int i,j;
        //n-1轮排序,每一轮最大值都会漂浮到最后,最后一个元素已经到合适位置故不需要n轮
        for(i=0;inums[j+1]){
                    int tmp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=tmp;
                }
            }
        }
    }
    // 6快速排序。基本思想是n个关键字中选取一个作为pivot,然后对剩下n-1个元素进行分类,所有小的放在前面区间A,
    // 大的放在后面区间B,此时pivot其实已经完成最终位置的排序。接下来就是对A和B区间也采用类似思路,直到每个区间长为1.
    // 选择pivot算法:
    // 1 选第一个元素,若输入是顺序了,则达不到1分2效果,A区间长的0,B区间长度N,效能差,pass
    // 2 随机选择,这里特别的设计了3数中值法,
    // 2.1 选择pivot。选择序列头尾和中间位置的3个元素的中值作为pivot,且在选择后,把这3个位置数值进行排序,避免后续再排序
    // 2.2 基于该pivot分割得A和B。i为序列开始,j为序列结束:
    //   i不断右移动,跳过小于pivot元素,同时j左移,跳过大于pivot元素
    //   当i=j
    //   将pivot与i最后到达的位置进行交换,这个位置也就是pivot最终排序的位置
    // 2.3 对剩下的A和B区间递归调用
    // 在进行pivot与i最后到达的位置交换时很可能就破坏了相等元素顺序性故不稳定
    int getPivot(vector&nums,int low,int high){
        // 3数中值法
        int mid=(low+high)/2;
        int tmp;
        // 3个元素的中值作为pivot,且在选择后,把这3个位置数值进行排
        if(nums[low]>nums[mid]){
            // lownums[high]){
            // lownums[high]){
            // mid&nums,int low,int high){
        int i,j;
        int pivot;
        if(lowi&&nums[++i]i&&nums[--j]>pivot){
                    
                }
                if(i&nums){
        part(nums,0,nums.size()-1);
    }
};

你可能感兴趣的:(排序算法,c++,算法)