zoukankan      html  css  js  c++  java
  • 各种排序算法

    快速排序:

     void QuickSort(vector<int>& nums, int lo, int hi){
            if(lo < hi){
                int p = partition(nums,lo,hi);
                QuickSort(nums,lo,p-1);
                QuickSort(nums,p+1,hi);
            }
        }
        int partition(vector<int>& nums, int lo, int hi){
            int pivot = nums[lo];
            while(lo < hi){
                while( lo < hi && nums[hi] > pivot) --hi;// nums[hi] < pivot 则从大到小排序
                nums[lo] = nums[hi];//小的放左边
                while( lo <hi && nums[lo] <= pivot) ++lo;
                nums[hi] = nums[lo];//大的放右边
            }
            nums[lo] = pivot;//pivot放中间
            return lo;
        }

    引出快速选择:选取第k大的元素:

    int findKthLargest(vector<int>& nums, int k) {
            srand(time(NULL));
            return QuickChoose(nums, 0, nums.size() - 1, k);
        }
        int QuickChoose(vector<int>& nums, int lo, int hi,int k){
            if(lo <= hi){
                int p = partition(nums,lo,hi);
                if(p == k - 1) return nums[p];//p左边元素都比p大
                else if( p > k-1) return QuickChoose(nums, lo, p-1, k);
                return QuickChoose(nums, p+1, hi,k);
            }
            return -1;
        }
        int partition(vector<int>& nums, int lo, int hi){
            int t = rand()%(hi - lo +1)+lo;//加入随机
            swap(nums[lo],nums[t]);
            int pivot = nums[lo];
            while(lo < hi){
                while( lo < hi && nums[hi] < pivot) --hi;
                nums[lo] = nums[hi];//大的放左边
                while( lo <hi && nums[lo] >= pivot) ++lo;
                nums[hi] = nums[lo];//小的放右边
            }
            nums[lo] = pivot;//pivot放中间
            return lo;
        }

    插入排序

    void InsertSort(vector<int>& nums){
            int n = nums.size();
            for(int i = 1; i< n; i++){
                int t = nums[i];//先取出nums[i]
                int j = i;
                while( j > 0 && nums[j-1] > t){
                    nums[j] = nums[j-1];
                    j--;
                }
                //找到正确的位置
                nums[j] = t;
            }
        }

    shell排序

     void ShellSort(vector<int>& nums){
            int n = nums.size();
            for(int k = n/2; k >= 1; k/=2){
                // InsertSort
                for(int i = k; i < n; i++){
                    int t = nums[i];
                    int j = i;
                    while(j - k >= 0 && nums[j-k] > t){
                        nums[j] = nums[j-k];
                        j -= k;
                    }
                    nums[j] = t;
                }
            }
        }

    归并排序:没有做空间优化

     void merge(vector<int>& nums,int lo, int hi){
            int mid = (lo+hi)/2;
            vector<int> temp;
            int i = lo, j = mid+1;
            while(i <= mid && j <= hi){
                if(nums[i] <= nums[j]) temp.push_back(nums[i++]);
                else temp.push_back(nums[j++]);
            }
            while(i <= mid) temp.push_back(nums[i++]);
            while(j <= hi) temp.push_back(nums[j++]);
            for(int i = lo; i <= hi; i++)
                nums[i] = temp[i-lo];
        }
        void MergeSort(vector<int>& nums, int lo, int hi){
            if(lo >= hi) return;
            int mid = (lo + hi)/2;
            MergeSort(nums,lo,mid);
            MergeSort(nums,mid+1,hi);
            merge(nums,lo,hi);
        }

    空间优化:

    void merge(vector<int>& nums,vector<int>& temp,int lo, int hi){
            int mid = (lo+hi)/2;
            int i = lo, j = mid+1;
            int t = lo;
            while(i <= mid && j <= hi){
                if(nums[i] <= nums[j]) temp[t++] = nums[i++];
                else temp[t++] = nums[j++];
            }
            while(i <= mid) temp[t++] = nums[i++];
            while(j <= hi) temp[t++] = nums[j++];
            for(int i = lo; i <= hi; i++)
                nums[i] = temp[i];
        }
        void MSort(vector<int>& nums,vector<int>& temp, int lo, int hi){
            if(lo >= hi) return;
            int mid = (lo + hi)/2;
            MSort(nums,temp,lo,mid);
            MSort(nums,temp,mid+1,hi);
            merge(nums,temp,lo,hi);
        }
        void MergeSort(vector<int>& nums){
            vector<int> temp(nums.size());
            MSort(nums,temp,0,nums.size() - 1);
            temp.clear();
        }

    堆排序

    void percdown(vector<int>& nums, int n, int index){
            int t = nums[index];// 先取出index处的值
            int pa = index, chi;
            while(pa*2+1 < n){
                chi = pa*2 + 1;
                if(chi != n-1 && nums[chi] <nums[chi+1])
                    chi++;
                if(t >= nums[chi]) break;//找到了正确的位置
                nums[pa] = nums[chi];
                pa = chi;//
            }
            nums[pa] = t;//把t放在正确的位置上
        }
        void HeapSort(vector<int>& nums){
            int n = nums.size();
            //建堆
            for(int i = n/2-1; i >= 0; i--)
                percdown(nums,n,i);
            for(int i = n-1; i >= 1; i--){
                //把最大的放在最后
                swap(nums[0],nums[i]);
                //调整交换后这个值的位置
                percdown(nums,i,0);
            }
        }

     基数排序

    参考:

    https://www.cnblogs.com/skywang12345/p/3603669.html

    https://www.cxyxiaowu.com/2106.html

    https://www.cnblogs.com/onepixel/p/7674659.html

    void RadixSort(vector<int>& nums){
            int n = nums.size();
            int max = INT_MIN;
            //找出长度最长的数组
            for(auto x:nums) if(abs(x) > max) max = x;
            //位数从最小位开始
            int exp = 1;
            //从-9到9共19个桶
            int buckets[19] = {0};
            vector<int> t(n);
            while(max/exp){
                memset(buckets,0,sizeof buckets);
                // 将数据出现的次数存储在buckets[]中
                for(int i = 0; i < n; i++)
                    buckets[nums[i]/exp%10 + 9]++;
                // 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
                for(int i = 1; i < 19; i++)
                    buckets[i] += buckets[i-1];
                // 将数据存储到临时数组output[]中,从后往前遍历是为了数据的稳定性
                for(int i = n-1; i >= 0; i--)
                    t[--buckets[nums[i]/exp%10+9]] = nums[i];
                //排序好的数组赋值给nums
                nums = t;
                exp*= 10;           
            }
        }
  • 相关阅读:
    <转载>asp.net中向数据库中插入数据时如何获得当前插入行的主键?
    <转载>HTML实体字符
    以当前系统默认的编码写入文件
    <转载>SQL Server 数据库 执行命令(方法 2:带参数的 SQL 命令)
    Windows7无法访问Windows2003共享的解决方案
    MVC Music Store 在线音乐商店示例分析(12)StoreManagerController
    MVC Music Store 在线音乐商店示例分析(6)ShoppingCart
    MVC Music Store 在线音乐商店示例分析(10)ShoppingCartController
    MVC Music Store 在线音乐商店示例分析(3)Album
    MVC Music Store 在线音乐商店示例分析(9)HomeController
  • 原文地址:https://www.cnblogs.com/Aliencxl/p/13189917.html
Copyright © 2011-2022 走看看