zoukankan      html  css  js  c++  java
  • 需要默写的一些排序算法→_→

    快速排序

    /*
    算法思想:在参加排序的序列中任意选择一个元素(通常称为分界元素或基准元素),把小于或等于
    分界元素的所有元素都移到分界元素的前面,把大于分界元素的所有元素都移到分界元素的后面,
    这样,当前参加排序的序列就被划分成前后两个子序列,其中前一个子序列中的所有元素都小于后
    一个子序列的所有元素,并且分界元素正好处于排序的最终位置上。然后分别对这两个子序列递归
    地进行上述排序过程,直到所有元素都处于排序的最终位置上,排序结束。
    */
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    using namespace std;
    
    //输出结果 
    void printData(vector<int> a);
    
    //将 pivot左边的数都小于他,右边的数都大于他 
    int Partition(vector<int>& a, int low, int high)
    {
        int pivot;
        
        //其实为了方便直接用第一个数做枢纽值很不好 
        pivot = a[low];
        
        //从线性表的两端交替地向中间扫描
        while (low < high)
        {
            while (low < high && a[high] >= pivot) high--;
            //比枢纽值小,就把他放到枢纽值左边 
            a[low] = a[high];
            while (low < high && a[low] <= pivot) low++;
            //比枢纽值大,就把他放到枢纽值右边 
            a[high] = a[low];
        } 
        // 此时, pivot左边的数据都小于他,右边的数据都大于他 
        a[low] = pivot;
        //返回枢纽值位置 
        return low;
    }
    
    void Qsort(vector<int>& a, int low, int high)
    {
        int pivotloc; 
        
        if (low < high)
        {
            //设置pivot值,然后排序, 使得 pivot左边的数都小于他,pivot右边的数都大于他, 
            //返回排序后pivot的位置 pivotloc, 然后再对其 两边的数据 递归排序 
            pivotloc = Partition(a, low, high);    
            //枢纽值(pivot)左边的数都小于 pivot, 排序所有小于pivot的值 
            Qsort(a, low, pivotloc - 1); 
            //pivot右边的数都大于pivot, 排序所有大于pivot的值 
            Qsort(a, pivotloc + 1, high);
        } 
    }
    
    //启动程序 
    void QuickSort(vector<int>& a, int size)
    {
        //设置排序的区间 
        Qsort(a, 0, size - 1);
        
        printData(a);
    }
     
    void printData(vector<int> a)
    {
        for (const auto& e : a) {
            cout << e << " ";
        }
        cout << endl;
    }
    
    int main()
    {
        vector<int> a = {-1, 2, 5, 6, 3, 10, 8, 20, 15, 12, 44, 23, 34};
        unsigned n = a.size();
        
        //插入排序 
        QuickSort(a, n);
        
        return 0;
    }

    堆排序

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    using namespace std;
    
    void printData(vector<int> a)
    {
        for (const auto& e : a) {
            cout << e << " ";
        }
        cout << endl;
    }
    
    //调整为大顶堆 
    void HeapAdjust(vector<int>& a, int low, int high)
    {
        int child;
        int tmp;
        //tmp: 父亲结点; 左结点的索引 < n ; 继续 判断孩子结点  
        // 2 * i : 获得左孩子结点索引 
        for (tmp = a[low]; low * 2 < high; low = child)
        {
            child = low * 2;    //获得左孩子结点索引 
            //如果孩子结点索引 尚未越界, 且  左孩子结点 小于 右孩子 结点    
            //就获得右孩子结点索引 
            if (child != high - 1 && a[child] < a[child + 1]) {
                child++;
            }
            if (tmp < a[child]) {      //父亲 < 孩子 
                a[low] = a[child];     //孩子 替换 父亲结点 
            }
            else {
                break;
            }
        } 
        a[low] = tmp;     //将父亲结点 插入 到比他大的 孩子结点位置.
        
    }
    
    //没有使用传引用,不改变 a 
    void HeapSort(vector<int>& a, int n)
    {
        //建立大顶堆
        for (int i = n / 2; i >= 0; i--)
        {
            HeapAdjust(a, i, n);    
        }
        
        for (int j = n - 1; j > 0; j--)
        {
            
            swap(a[0], a[j]);
            //将 a[1..i] 重新调整为大顶堆
            HeapAdjust(a, 0, j); 
        }
        
        printData(a);
    }
     
    int main()
    {
        vector<int> a = {-1, 2, 5, 6, 3, 10, 8, 20, 15, 12, 44, 23, 34};
        unsigned n = a.size();
        
        //插入排序 
        HeapSort(a, n);
        
        return 0;
    }

    不懂可以看这个: https://www.cnblogs.com/0zcl/p/6737944.html

    归并排序

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int test[100] = { 0 };
    
    void Merge(int *test, int lo, int mid, int hi); 
    void MergeSort(int *test, int lo, int hi) {
        if (hi - lo < 2) return;
        int mid = (lo + hi) >> 1;
        MergeSort(test, lo, mid);                           //对前半段排序
        MergeSort(test, mid, hi);                           //对后半段排序
        Merge(test, lo, mid, hi);                           //归并
    }
    
    //归并---O(nlogn), T(n) = 2T(n/2) + O(n)
    void Merge(int *test, int lo, int mid, int hi) {
        //A用来存放合并后的向量,B,C进行比较(前后子向量比较)
        int  *A = test + lo;          //合并后的向量A[0,hi-lo) = int s[lo,hi)
        int lb = mid - lo;
        int  *B = new int [lb];        //前子向量 B[0,lb) = int s[lo,mi)
        for (int i = 0; i < lb; B[i] = A[i++]);   //复制前子向量
        int lc = hi - mid;
        int  *C = test + mid;         //后子向量
        for (int i = 0, j = 0, k = 0; (j < lb || k < lc);) {
            //B[i], C[k]中小者转至A的末尾.        
            //因为C本来就占据A中,不需要考虑提前耗尽情况
            if ((j < lb) && (k >= lc || C[k] >= B[j]))      //C[k]已无或不小
                A[i++] = B[j++];
            if ((k < lc) && (j >= lb || B[j] >= C[k]))      //B[k]已无或不小
                A[i++] = C[k++];
        }
        delete[]B;
    }
    
    
    int main()
    {
        //用来测试 非模板写的 归并排序 算法
        
        int Test[13] = { 1, 5, 2, 3, 6, 8, 9, 10, 13, 12, 4, 7, 11 };
        
        MergeSort(Test, 0, 13);
        
        for (int i = 0; i < 13; i++)
            cout << Test[i] << " ";
        cout << endl;
    
        return 0;
    
    }

    插入排序

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    using namespace std;
    
    void printData(vector<int> a)
    {
        for (const auto& e : a) {
            cout << e << " ";
        }
        cout << endl;
    }
    
    //没有使用传引用,不改变 a 
    void InsertSort(vector<int> a, int n)
    {
        for (int i = 1; i < n; i++)
        {
            if (a[i] < a[i - 1])  //当前选择的数 < 前一个数 
            {                     //就把放到前面去 
                int    j = i - 1;
                int temp = a[i];
                //当前的数跟前面数比较, 一直小,前面的数就一直后移 
                while (j >= 0 && temp < a[j])
                {
                    a[j + 1] = a[j];
                    j--;
                }
                a[j + 1] = temp; 
            }
        }
        
        printData(a);
    }
    
    //折半插入排序, 只是使用折半查找的方法来寻找插入位置
    void BinInsertSort(vector<int> a, int n)
    {
        int low, high, mid, tmp;
        for (int i = 1; i < n; i++)    
        {
            tmp = a[i];
            low = 0, high = i - 1;
            while (low <= high)
            {
                mid = (low + high) / 2;
                if (tmp > a[mid]) {
                    low = mid + 1;
                }
                else {
                    high = mid - 1;
                }
            }
            for (int j = i; j > low; j--) {
                a[j] = a[j - 1];          //前移 
            }
            a[low] = tmp;
        }
        
        printData(a);
    } 
     
    int main()
    {
        vector<int> a = {-1, 2, 5, 6, 3, 10, 8, 20, 15, 12};
        unsigned n = a.size();
        
        //插入排序 
        InsertSort(a, n);
        
        //折半插入排序
        BinInsertSort(a, n);
        
        return 0;
    }

    选择排序

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    using namespace std;
    
    void printData(vector<int> a)
    {
        for (const auto& e : a) {
            cout << e << " ";
        }
        cout << endl;
    }
    
    //没有使用传引用,不改变 a 
    void ChooseSort(vector<int> a, int size)
    {
        int min = 0, i, j;
        for (i = 0; i < size - 1; i++)
        {
            min = i;              //此假设为最小值的下标
            for (j = min + 1; j < size; j++)
            {
                if (a[min] > a[j]) {
                    min = j;      //找出当前位置 最小值的下标 
                }
            } 
            //如果假设的最小的下标改变了,就将最小下标位置元素
            //与 i 位置交换,则 i 为当前位置最小的元素
            if (i != min) {
                swap(a[i], a[min]);
            }
        }
        
        printData(a);
    }
     
    int main()
    {
        vector<int> a = {-1, 2, 5, 6, 3, 10, 8, 20, 15, 12, 44, 23, 34};
        unsigned n = a.size();
        
        //插入排序 
        ChooseSort(a, n);
        
        return 0;
    }

    冒泡排序

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    using namespace std;
    
    void printData(vector<int> a)
    {
        for (const auto& e : a) {
            cout << e << " ";
        }
        cout << endl;
    }
    
    //没有使用传引用,不改变 a 
    void BubbleSort(vector<int> a, int n)
    {
        bool ordered;
        //外层循环 -- 一共进行比较的趟数( n - 1 ) 
        for (int i = 0; i < n - 1; i++)
        {
            ordered = true;
            //每趟需要比较的次数 
            //每次循环后,可以依次得到Max,次Max, 次次max...... 
            for (int j = 0; j < n - i - 1; j++)
            {
                //每次选出  当前位置元素  应当所在的  最大位置, 并交换
                if (a[j] > a[j + 1]) 
                {
                    swap(a[j], a[j + 1]);
                    //只要交换,则说明交换前,不是有序
                    ordered = false;
                }
            }
            //一次交换都没有,说明已经没有逆序对,则已经有序,直接退出循环! 
            if (ordered) {
                break;
            }
        }
        
        printData(a);
    }
     
    int main()
    {
        vector<int> a = {-1, 2, 5, 6, 3, 10, 8, 20, 15, 12};
        unsigned n = a.size();
        
        //插入排序 
        BubbleSort(a, n);
        
        return 0;
    }
  • 相关阅读:
    java实现孪生素数
    java实现孪生素数
    java实现孪生素数
    java实现孪生素数
    java实现孪生素数
    java实现连续数的公倍数
    java实现连续数的公倍数
    mysql千万级数据量根据索引优化查询速度
    MySQL特异功能之:Impossible WHERE noticed after reading const tables
    MySQL:浅析 Impossible WHERE noticed after reading const tables
  • 原文地址:https://www.cnblogs.com/douzujun/p/8471261.html
Copyright © 2011-2022 走看看