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

    //  此版本为调整优化好的快速排序算法实现。
    # include <iostream>
    # include <vector>
    using namespace std;
    int Partition(vector<int> &arr, int low, int high)
    {
        int pivot;                // 划分后基准记录的位置
        int pivotkey = arr[low]; // 用区间的第一个值作为基准,也可以采用其他方式,比如三数取中
        while (low < high)
        {
            while (low < high && arr[high] >= pivotkey) // 先从右向左扫描
                high--;
            if (low < high)      // 每次必须有判断,因为有可能在此时出现low>high的情况
                arr[low++] = arr[high];
            while (low < high && arr[low] <= pivotkey) // 再从左向右扫描
                low++;
            if(low < high)
                arr[high--] = arr[low];
        }
        pivot = low;           // 找出基准位置
        arr[pivot] = pivotkey; // 基准位置定位
        return pivot;
    }
    // 典型的分治法的思想
    void quicksort(vector<int> &arr, int low, int high)
    {
        if (low < high)  // 仅当区间长度大于 1 时才排序
        {
            int pivot = Partition(arr, low, high);  // 分解,找出基准
            quicksort(arr, low, pivot-1);           // 递归求解左子区间
            quicksort(arr, pivot + 1, high);        // 递归求解右子区间
        }
    }
    int main ()
    {
        vector<int> arr;
        int temp;
        while (cin >> temp)
        {
            arr.push_back(temp); // 将数存入数组
        }
        quicksort(arr, 0, arr.size() - 1);
        for(auto i : arr)
            cout << i << endl;
        return 0;
    }
    // 优化的冒泡算法实现
    # include <iostream>
    # include <vector>
    using namespace std;
    void BubbleSort(vector<int> &arr)
    {
        int i , j, temp,len;
        len =  arr.size();
        for (i = 0; i < len - 1; i++)  // 外层循环控制无序区的终点位置
        {
            bool flag = true;
            for (j = len - 1; j > i; j--) //内层控制每次比较的位置
            {
                if (arr[j] < arr[j - 1])
                {
                    temp = arr[j];
                    arr[j] = arr[j -1];
                    arr[j - 1] = temp;
                    flag = false;
                }
            }
            if (flag)
                break;
        }
    }
    int main()
    {
        vector<int> arr;
        int temp;
        while (cin >> temp)
        {
            arr.push_back(temp); // 将数存入数组
        }
        BubbleSort(arr);
        cout <<"after sort: "<< endl;
        for(auto i : arr)
            cout << i << endl;
        return 0;
    }
    // 简单选择算法实现,相比于冒泡排序,最大的特点是数据交换移动次数较少,找到合适的关键字(最小值的位置)再交换
    # include <iostream>
    # include <vector>
    using namespace std;
    void SelectSort(vector<int> &arr)
    {
        int i , j, temp,len, minindex;
        len =  arr.size();
        for (i = 0; i < len - 1; i++)  // 外层循环控制无序区的起点位置
        {
            minindex = i;
            for (j = i + 1; j <= len ; j++) //内层控制每次比较的位置,注意范围控制
            {
                if (arr[j] < arr[minindex])
                    minindex = j;
            }
            if (minindex != i)  // 若有比当前值还小的最小值,则将最小值放到无序区的起点位置
            {
                temp = arr[minindex];
                arr[minindex] = arr[i];
                arr[i] = temp;
            }
        }
    }
    int main()
    {
        vector<int> arr;
        int temp;
        while (cin >> temp)
        {
            arr.push_back(temp); // 将数存入数组
        }
        SelectSort(arr);
        cout <<"after sort: "<< endl;
        for(auto i : arr)
            cout << i << endl;
        return 0;
    }
    // 直接插入排序算法实现: 基本操作是讲一个记录插入到已经排好序的有序表汇总,
    // 从而得到 一个新的、记录数增1的有序表
    // 时间复杂度: O(n^2)
    // author: SimplePaul
    # include <iostream>
    # include <vector>
    using namespace std;
    void InsertSort(vector<int> &arr)
    {
        int i , j, temp,len;
        len =  arr.size();
        for (i = 1; i <= len - 1; i++)  //
        {
            if(arr[i] < arr[i-1])   // 若当前比前一个小,则需要交换,否则不交换
            {
                temp = arr[i];    // 保存当前的值
                for ( j = i - 1; arr[j] > temp && j >= 0; j--) // j>= 0的条件容易忘
                {
                    arr[j + 1] = arr[j];   // 记录后移,直到当前值比temp要小
                }
                arr[j + 1] = temp;
            }
        }
    }
    int main()
    {
        vector<int> arr;
        int temp;
        while (cin >> temp)
        {
            arr.push_back(temp); // 将数存入数组
        }
        InsertSort(arr);
        cout <<"after sort: "<< endl;
        for(auto i : arr)
            cout << i << endl;
        return 0;
    }
    // 希尔排序算法实现: 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进
    // 该方法又称缩小增量排序,希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,
    //取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录
    //放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是
    //有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。
    
    // 相当于是     插入排序只是执行了希尔排序的gap=1的情况
    // 时间复杂度: O(nlog(n))~O(n^2)  ,不稳定排序
    // author: SimplePaul
    
    # include <iostream>
    # include <vector>
    using namespace std;
    void ShellSort(vector<int> &arr)
    {
        int i , j, temp,len,gap;
        len =  arr.size();
        gap = len / 2;       // 取增量
        while (gap >= 1)
        {
    
            for (i = gap; i <= len - 1; i += gap)  // 进行插入排序,相当于原来每次插入排序的间隔为1,现在为gap
            {
                if(arr[i] < arr[i - gap]) // 若当前比前一个(前一个指相差gap的前一个值)小,则需要交换,否则不交换
                {
                    temp = arr[i];        // 保存当前的值
                    for ( j = i - gap; arr[j] > temp && j >= 0; j -= gap) // j>= 0的条件容易忘
                    {
                        arr[j + gap] = arr[j];   // 每次记录后移gap,直到当前值比temp要小
                    }
                    arr[j + gap] = temp;   
                }
            }
            gap /= 2;   // 设置新的增量
        }
    
    }
    int main()
    {
        vector<int> arr;
        int temp;
        while (cin >> temp)
        {
            arr.push_back(temp); // 将数存入数组
        }
        ShellSort(arr);
        cout <<"after sort: "<< endl;
        for(auto i : arr)
            cout << i << endl;
        return 0;
    }

     堆排序实现:参考源

    // 堆排序实现:
    // 复杂度: O(NlogN)
    //
    堆排序快速排序归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法
    #include <iostream>
    using namespace std;
    // 最大堆的向下调整算法  MaxHeapDown()
    // 数组实现的堆中,第N个结点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)
    // 其中,N为数组下标索引值,如数组第一个数对应的N为0。
    // 参数说明:
    //          a: 待排序的数组
    //          start: 被下调节点的起始位置(一般为0,表示从第一个开始)
    //          ends: 截止范围(一般为数组中最后一个元素的索引)
    void MaxHeapDown(int* a, int start, int ends)
    {
        int c = start;  // 当前(current)节点的位置
        int l = 2 * c + 1; // 左(left)孩子的位置
        int tmp = a[c];    // 当前节点的大小
        for (; l <= ends; c = l, l = 2*l + 1)
        {
            // l 是左孩子, l + 1 是右孩子
            if ( l < ends && a[l] < a[l + 1])
                l++;  // 左右两个孩子中选择较大者
            if (tmp >= a[l])
                break;   // 若当前节点的值比两个孩子中的大者还大 就结束循环
            //若是需要交换则执行下面的步骤
            a[c] = a[l];
            a[l] = tmp;
        }
    }
    // 堆排序(从小到大):  a : 待排数组;  n: 数组的长度
    void HeapSortAsc(int *a, int n)
    {
        int i, tmp;
        // 从(n/2 - 1) --> 0 顺序遍历,之后得到的数组实际上是一个最大二叉堆
        // 即从第一个有孩子的节点开始遍历调整,
        for (i = n / 2 - 1; i >= 0; i--) // 相当于建好一个堆
            MaxHeapDown(a, i, n - 1);
    
        //从最后一个元素开始对序列进行调整,直到第一个元素
        for (i = n - 1; i > 0; i--)
        {
            // 交换a[0]和 a[i],交换后a[i]是数组中最大的
            tmp = a[0];
            a[0] = a[i];
            a[i] = tmp;
            //再调整a[0>>>>i-1],使得其仍为一个最大堆
            MaxHeapDown(a, 0, i - 1);
        }
    }
    int main()
    {
        int i;
        int a[] = {20,30,90,40,70,110,60,10,100,50,80};
        int len = (sizeof(a) / (sizeof(a[0])));
        cout << "before sort:";
        for (i = 0; i < len; i++)
        {
            cout << a[i] << " ";
        }
        cout << endl;
        HeapSortAsc(a, len);
        cout << "after sort:";
        for (i = 0; i < len; i++)
        {
            cout << a[i] << " ";
        }
        cout << endl;
        return 0;
    }

    // 一个例子:寻找最小的K个数

    归并排序:待更新。。。

  • 相关阅读:
    ARP投毒攻击
    sniffer简单使用
    MAC泛洪攻击
    又是一题反序列化了解一下???
    关于parse_str变量覆盖分析
    超级ping(多线程版)
    文本输入框input将输入转换为统一大小写
    通俗易懂JSONP讲解
    通俗易懂JSONP讲解
    Fastjson主要接口和类库说明
  • 原文地址:https://www.cnblogs.com/simplepaul/p/6755536.html
Copyright © 2011-2022 走看看