• 常见排序算法


    #include <iostream>
    
    class Sort
    {
    public:
    	Sort();
    	~Sort();
    	void BubbleSort(int* nums,int len); 
    	void InsertSort(int* nums, int len);
    	void SelectionSort(int* nums, int len);
    	void QuickSort(int* nums, int len,int left,int right);
    	void HeapSort(int* nums, int len);
    	void MergeSort(int* nums, int start, int end);
    
    	void ShowNums(int* nums, int len);
    private:
    	void max_heap(int nums[], int start, int end);
    	void Merge(int* nums, int start, int mid, int end);
    	void swap(int& a, int& b);
    };
    
    #include "pch.h"
    #include "Sort.h"
    
    
    
    
    Sort::Sort()
    {
    }
    
    Sort::~Sort()
    {
    }
    
    //冒泡 时间复杂度:平均:O(N^2) 最好:O(N)  最坏:O(N~2)  稳定性:稳定
    void Sort::BubbleSort(int * nums, int len)
    {
        if (nums == nullptr|| len <= 1)
            return;
    
        for (int i = 0; i < len - 1; i++) {
            //一趟排序把最大的放到最后了
            for (int j = 0; j < len-2-i ; j++) {
                if (nums[j] > nums[j+1]) {
                    swap(nums[j], nums[j+1]);
                }
            }
        }
    }
    
    //直接插入排序 时间复杂度:平均:O(N^2) 最好:O(N)  最坏:O(N~2)  稳定性:稳定
    void Sort::InsertSort(int * nums, int len)
    {
        if (nums == nullptr || len <= 1)
            return;
    
        for (int i = 0; i < len; i++) {
            //当前值往前比较,如果当前值比前面的值大就跳出下面循环,前面都是有序的
            for (int j = i; j > 0 && nums[j] < nums[j - 1]; j--) {
                swap(nums[j], nums[j - 1]);
            }
        }
    }
    
    //直接选择排序 时间复杂度:平均:O(N^2) 最好:O(N^2)  最坏:O(N~2)  稳定性:不稳定
    void Sort::SelectionSort(int * nums, int len)
    {
        if (nums == nullptr || len <= 1)
            return;
        
        for (int i = 0; i < len; i++) {
            int index = i;
            //每次找到第i个最小的
            for (int j = i + 1; j < len; j++) {
                if (nums[index] > nums[j]) {
                    index = j;
                }
            }
            //如果当前不是第i个最小的就交换
            if (index != i) {
                swap(nums[i], nums[index]);
            }
        }
    }
    
    //快速排序 时间复杂度:平均:O(NlogN) 最好:O(NlogN)  最坏:O(N~2)  稳定性:不稳定
    void Sort::QuickSort(int * nums, int len, int left, int right)
    {
        //left >= right 这个条件容易忘记
        if (nums == nullptr || len <= 1 || left >= right)
            return;
    
        int key = nums[left];
        int i = left;
        int j = right;
        //一次while循环将比key小的都放在key的左边,比key大的都放在右边
        //一次循环后i==j;
        while (i < j) {
            while (i < j && key <= nums[j]) {
                j--;
            }
            nums[i] = nums[j];
    
            while (i<j && key >= nums[i]) {
                i++;
            }
            nums[j] = nums[i];
        }
        nums[i] = key;
    
        QuickSort(nums, len, left, i-1);//对key左边的继续排序
        QuickSort(nums, len, i + 1, right);//对key右边的继续排序
    }
    
    //堆排序 时间复杂度:平均:O(NlogN) 最好:O(NlogN)  最坏:O(NlogN)  稳定性:不稳定
    void Sort::HeapSort(int * nums, int len)
    {
        if (nums == nullptr || len <= 1)
            return;
    
        //调整为大顶堆,从最后一个父节点开始
        for (int i = len / 2 - 1; i >= 0; i--) {
            max_heap(nums, i, len - 1);
        }
    
        //先将第一个元素和已经排好的元素前一位做交换,再从新调整(刚调整的元素之前的元素),直到排序完毕
        for (int i = len - 1; i > 0; i--) {
            swap(nums[0], nums[i]);
            max_heap(nums, 0, i-1);
        }
    }
    
    //归并排序 时间复杂度:平均:O(NlogN) 最好:O(NlogN)  最坏:O(NlogN)  稳定性:稳定
    void Sort::MergeSort(int * nums, int start,int end)
    {
        if (nums == nullptr || start == end)
            return;
        
        int mid = start + (end - start) / 2;
        MergeSort(nums, start, mid);
        MergeSort(nums, mid + 1, end);
    
        //两两合并
        Merge(nums, start, mid, end);
    }
    
    //构造大顶堆
    void Sort::max_heap(int nums[], int start, int end)
    {
        if (start == end)
            return;
    
        int parent = start;
        int element = 2 * parent + 1;
    
        while (element <= end) {
            //比较左右孩子哪个大
            if (element+1 <= end && nums[element] < nums[element+1]) {
                element++;
            }
            //与父节点比较大小,如果比父节点大,交换后则继续对后面的节点进行比较
            if (nums[element] > nums[parent]) {
                swap(nums[element], nums[parent]);
                parent = element;
                element = 2 * parent + 1;
            }
            else {
                return;
            }
        }
    
    }
    
    //合并
    void Sort::Merge(int * nums, int start, int mid, int end)
    {
        //start是第一部分的起点,mid+1是第二部分的起点
        int* temp = new int[end - start + 1];
        int i = start;
        int j = mid + 1;
        int index = 0;
        
        //两部分进行排序
        while (i <= mid && j <= end) {
            if (nums[j] > nums[i]) {
                temp[index++] = nums[i++];
            }
            else {
                temp[index++] = nums[j++];
            }
        }
    
        //如果i这边还有剩下的
        while (i <= mid) {
            temp[index++] = nums[i++];
        }
    
        //如果j这边还有剩下的
        while (j <= end) {
            temp[index++] = nums[j++];
        }
    
        for (int i = 0; i < index; i++) {
            nums[start+i] = temp[i];
        }
    
        delete[] temp;
    }
    
    
    void Sort::ShowNums(int * nums, int len)
    {
        if (nums == nullptr || len < 0)
            return;
    
        for (int i = 0; i < len; i++) {
            std::cout << nums[i] << " ";
        }
        std::cout << std::endl;
    }
    
    void Sort::swap(int & a, int & b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
  • 相关阅读:
    mislider jQuery响应式圆形图片轮播图特效制作(图片轮播效果二)
    CSS3 animation实现图片轮播效果 自动显示 无需使用js 含代码(图片轮播效果一)
    HTML5 Canvas 学习笔记(canvas绘制线条、矩形、多边形、圆、自定义图像)
    网页右侧悬浮窗制作
    用JavaScript实现选项卡功能
    XML 可扩展的标记性语言
    继承
    原型和原型链
    HTTP 协议类
    DOM 事件
  • 原文地址:https://www.cnblogs.com/darkif/p/10138358.html
Copyright © 2020-2023  润新知