• 【排序算法汇总】


    一、合并排序

       1.思路:

        将包含n个元素的序列均分成各自包含n/2个元素的子序列,然后对这两个子序列递归划分,最后把已经排好序的子序列合并成一个有序序列。

       2.代码:  

    #include <iostream>
    using namespace std;
    void Merge(int *array, int low, int middle, int high)  //合并
    {
        int *A = new int[high - low + 1];  //临时数组,存储个数为high - low + 1个数据
        int i = low;
        int j = middle + 1;
        int k = 0;
        while(i <= middle && j <= high)  //直至前半部或后半部数据完全录入暂存
        {
            if(array[i] < array[j])  //如果前半部的数据小于后半部的,前半部数据暂存
                A[k++] = array[i++];
            else                     //否则后半部数据暂存,并下标自加
                A[k++] = array[j++];
        }
    
        while(i <= middle) //保证前半部数据录入暂存
            A[k++] = array[i++];
        while(j <= high)   //保证后半部数据录入暂存
            A[k++] = array[j++];
        for(i = low; i <= high; i++)  //将暂存的数据重新填充至array[low]--array[high]中
            array[i] = A[i - low];
    }
     
    void MergeSort(int *array, int low, int high)
    {
        int middle;  //二分
        if(low < high)
        {
            middle = (low + high) / 2;  //二分
            MergeSort(array, low, middle); //前半部
            MergeSort(array, middle + 1, high);  //后半部
            Merge(array, low, middle, high);  //合并
        }
    }
    int main()
    {    
        /*int n;
        cin>>n;  //录入需要排列的个数
        int *array = new int[n];
        cout<<endl<<"请输入数据:"<<endl;
        for(int i = 0; i < n; i++)
        {
            cin>>array[i];  //录入未排序的数据
        }*/
        int n=10;
        int array[10]={3,2,5,7,3,8,4,5,8,6};
        MergeSort(array, 0, n - 1);  //进行排序
        cout<<"排列后数据:"<<endl;
        for(int j = 0; j < n; j++)  //输出排列结果
        {
            cout<<array[j]<<" ";
        }
          cout<<endl;
        return 0;
    }

      二、快速排序

      1.思想:

       把A分成两个部分,支点为q,并且满足左边的都<A[q],右边的都>A[q],子问题解决了原问题就解决了。

       2.代码:

     

    #include<iostream>
    using namespace std;
    int partition(int *arr, int left, int right)  //找基准数 划分
    {
        int temp = arr[left];//支点
        int i = left + 1 ;//左指针,寻找>支点数据的位置
        int j = right;//右指针,寻找<支点数据的位置
        
    
        while(i <= j)
        {
            while (arr[i] < temp) i++;//左位置
            while (arr[j] > temp) j--;//右位置
            if (i < j)
                swap(arr[i++], arr[j--]);
            else i++;
        }
        swap(arr[j], arr[left]);
        return j;
    
    }
    
    void quick_sort(int arr[], int left, int right) 
    {
        if (left > right)
            return;
        int j = partition(arr, left, right);
        quick_sort(arr, left, j - 1);
        quick_sort(arr, j + 1, right);
    }
    int main()
    {
        int a[10]={3,1,5,7,4,7,9,7,2,4};
        quick_sort(a,0,9);
        for(int i=0;i<=9;i++)
            cout<<a[i]<<' ';
        return 0;
    }

     三、冒泡、插入排序  

    #include<iostream>
    using namespace std;
    void sort1(int *a,int n)//冒泡排序
    {
       int i,j,tmp;
       for(i=0;i<n;i++)
           for(j=i+1;j<n;j++)
               if(a[i]>a[j])
               {
                 tmp=a[i];
                 a[i]=a[j];
                 a[j]=tmp;
               }
    }
    void sort2(int *a,int n)//插入排序
    {
        int i,j,k;
        for(i=1;i<n;i++)
        {
            for(j=i-1;j>=0;j--)
                if(a[i]>a[j])
                    break;
            int tmp=a[i];
            for(k=i-1;k>j;k--)
                a[k+1]=a[k];
            a[j+1]=tmp;
        }
    
    }
    int partition(int *a,int left,int right)
    {
        int tmp=a[left];
        int i=left+1;
        int j=right;
        while(i<=j)
        {
            while(a[i]<tmp)i++;
            while(a[j]>tmp)j--;
            if(i<j)
                swap(a[i++],a[j--]);
            else i++;
        }
        swap(a[j],a[left]);
        return j;
    }
    void sort3(int *a,int left,int right)//快速排序
    {
        if(left>right)return;
        int j=partition(a,left,right);
        sort3(a,left,j-1);
        sort3(a,j+1,right);
    }
    void merge(int *a,int left,int middle,int right)
    {
        int *A = new int[right-left + 1];  
        int i = left;
        int j = middle + 1;
        int k = 0;
        while(i <= middle && j <= right)  //直至前半部或后半部数据完全录入暂存
        {
            if(a[i] < a[j])  //如果前半部的数据小于后半部的,前半部数据暂存
                A[k++] = a[i++];
            else                     //否则后半部数据暂存,并下标自加
                A[k++] = a[j++];
        }
    
        while(i <= middle) //保证前半部数据录入暂存
            A[k++] = a[i++];
        while(j <= right)   //保证后半部数据录入暂存
            A[k++] = a[j++];
        for(i = left; i <= right; i++)  //将暂存的数据重新填充至array[low]--array[high]中
            a[i] = A[i - left];
    
    }
    void sort4(int *a,int left,int right)//归并排序
    {
      int middle;
      if(left<right)
      {
          middle=(left+right)/2;
          sort4(a,left,middle);
          sort4(a,middle+1,right);
          merge(a,left,middle,right);
      }
    }
    int main()
    {
        int n=5;
        int *a=new int[n];
        for(int i=0;i<n;i++)
            cin>>a[i];
        sort4(a,0,n-1);
        for(int j=0;j<n;j++)
            cout<<a[j]<<' ';
    }

     四、基数排序

       1.思想:

      

       2.代码:

      

    /*
     * 获取数组a中最大值
     *
     * 参数说明:
     *     a -- 数组
     *     n -- 数组长度
     */
    int get_max(int a[], int n)
    {
        int i, max;
    
        max = a[0];
        for (i = 1; i < n; i++)
            if (a[i] > max)
                max = a[i];
        return max;
    }
    
    /*
     * 对数组按照"某个位数"进行排序(桶排序)
     *
     * 参数说明:
     *     a -- 数组
     *     n -- 数组长度
     *     exp -- 指数。对数组a按照该指数进行排序。
     *
     * 例如,对于数组a={50, 3, 542, 745, 2014, 154, 63, 616};
     *    (01) 当exp=1表示按照"个位"对数组a进行排序
     *    (02) 当exp=10表示按照"十位"对数组a进行排序
     *    (03) 当exp=100表示按照"百位"对数组a进行排序
     *    ...
     */
    void count_sort(int a[], int n, int exp)
    {
        int output[n];             // 存储"被排序数据"的临时数组
        int i, buckets[10] = {0};
    
        // 将数据出现的次数存储在buckets[]中
        for (i = 0; i < n; i++)
            buckets[ (a[i]/exp)%10 ]++;
    
        // 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
        for (i = 1; i < 10; i++)
            buckets[i] += buckets[i - 1];
    
        // 将数据存储到临时数组output[]中
        for (i = n - 1; i >= 0; i--)
        {
            output[buckets[ (a[i]/exp)%10 ] - 1] = a[i];
            buckets[ (a[i]/exp)%10 ]--;
        }
    
        // 将排序好的数据赋值给a[]
        for (i = 0; i < n; i++)
            a[i] = output[i];
    }
    
    /*
     * 基数排序
     *
     * 参数说明:
     *     a -- 数组
     *     n -- 数组长度
     */
    void radix_sort(int a[], int n)
    {
        int exp;    // 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...
        int max = get_max(a, n);    // 数组a中的最大值
    
        // 从个位开始,对数组a按"指数"进行排序
        for (exp = 1; max/exp > 0; exp *= 10)
            count_sort(a, n, exp);
    }

       3.参考:

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

    五、计数排序

      1.思想:

      设置MXA(待排序数组的最大值)个桶,分别将数放入各个桶,再收集即可。

      2.代码:

     

    #include<iostream>
    using namespace std;
    int main() {
        int book[100] = {0};//标志位,标记桶内数据量
        int input[11];
        int heap[100] = {0};//初始化堆,排序0到100之间的数,heap[排序范围最大值]
        int i,j;
        for (size_t i = 1; i <=10 ; i++)
        {
            cin >> input[i];
            book[input[i]] += 1;
            heap[input[i]] = 1;
        }
        for (size_t i = 0; i <100 ; i++)
        {
            if (heap[i]==1) {
                for ( j = 1;j<=book[i]; j++)
                {
                    cout << i << " ";//输出排序结果
                }
            }
        }
        cout << endl;
        getchar();
    
        return 0;
    }

     六、堆排序

      1.思想:

      将数组建成最大(小)堆,然后依次删除最大元素即可。

      2.代码:

      3.参考:

      https://www.cnblogs.com/chengxiao/p/6129630.html

     

     

     

     

     

     
  • 相关阅读:
    数据挖掘、数据分析的书籍推荐
    跳槽时间如何选择
    求职网站总结
    Eclipse中Applet程序运行时Applet小程序大小的设置
    统计学习导论:基于R应用——第五章习题
    统计学习导论:基于R应用——第四章习题
    统计学习导论:基于R应用——第三章习题
    Windows环境下安装IPython NoteBook
    centos7上mysql无法启动也没有日志
    CentOS 6.4下Squid代理服务器的安装与配置
  • 原文地址:https://www.cnblogs.com/EstherLjy/p/9347958.html
Copyright © 2020-2023  润新知