zoukankan      html  css  js  c++  java
  • 十大基本排序原理复杂度分析,动图演示,C++代码演示

    一    总述

    排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括:

    冒泡排序

    排序原理

    冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成

    算法步骤

    比较相邻的元素。如果第一个比第二个大,就交换他们两个。

    对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

    针对所有的元素重复以上的步骤,除了最后一个。

    持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

    动图演示

    代码演示(C++)

    void BubbleSort(int a[] , int n)//冒泡排序
    {
        int flag;
        for(int i=0;i<n-1;i++)
        {
            flag = 0;
            for(int j=n-1;j>i;j--)
            {
                if(a[j] < a[j-1])
                {
                    swap(a[j] , a[j-1]);
                    flag = 1;
                }
            }
            if(flag == 0)
                return;
        }
    }

    选择排序 

    排序原理

    选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。

    排序步骤

    首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

    再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

    重复第二步,直到所有元素均排序完毕。

    动图演示

    代码演示(C++)

    void SelectSort(int a[] , int n)//选择排序1
    {
        for(int i=0;i<n;i++)
        {
            for (int j=i+1;j<n;j++)
            {
                if(a[i] >= a[j])
                    swap(a[i] , a[j]);
            }
        }
    }

    插入排序

    排序原理

    将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

    从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

    动图演示

     

    直接插入排序代码演示(C++)

    void InsertSort(int a[] , int n)//直接插入排序,非递减排序
    {
        int i,j,temp;
        for (i=1;i<n;i++)
        {
            if(a[i] < a[i-1])
            {
                temp = a[i];
                for(j=i-1;temp<a[j];j--)
                {
                    a[j+1] = a[j];
                }
                a[j+1] = temp;
            }
    
        }
    
    }

     

    折半插入排序代码演示(C++)

    void HalfInsertSort(int a[] , int n)//折半插入排序
    {
        int i,j,temp,low,high,mid;
        for(i=1;i<n;i++)
        {
            temp = a[i];
            low = 0,high = i-1;
            while(low <= high)
            {
                mid = (low + high) / 2;
                if(temp < a[mid])
                {
                    high = mid - 1;
                }
                else
                {
                    low = mid + 1;
                }
            }
            for(j=i-1;j>=high+1;j--)
            {
                a[j+1] = a[j];
            }
            a[high+1] = temp;
        }
    }

    快速排序

    排序步骤

    1. 从数列中挑出一个元素,称为 "基准"(pivot);

    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

    动图演示

    代码演示(C++)

    //严蔚敏《数据结构》标准分割函数
     Paritition1(int A[], int low, int high) {
       int 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];
       }
       A[low] = pivot;
       return low;
     }
    
     void QuickSort(int A[], int low, int high) //快排母函数
     {
       if (low < high) {
         int pivot = Paritition1(A, low, high);
         QuickSort(A, low, pivot - 1);
         QuickSort(A, pivot + 1, high);
       }
     }

    基数排序

    排序原理

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

    动图演示

    代码演示(C++)

    /************************基数排序****************************/
    int MaxBit(int data[] , int n)//求data数组中的最大值的位数
    {
        int maxNum = data[0];
        for(int i=1;i<n;i++)//求出data数组的最大值
        {
            if(data[i] > maxNum)
            {
                 maxNum = data[i];
            }
        }
        int maxDigit = 1;
        while(maxNum/10)//求最大值有几位
        {
            maxNum /= 10;
            maxDigit++;
        }
    
        return maxDigit;//返回最大值的位数
    }
    
    void RadixSort(int data[] , int n)//基数排序
    {
        int circle = MaxBit(data , n);//计算总循环数
        int temp[n],count[10];
        int p = 1;//除数,每次循环变化一次,以便求一个数字的不同位数上的数字
        while(circle--)
        {
    
            memset(count , 0 , sizeof(count));//记载数组清零
            for(int i=0;i<n;i++)//记载每个data数组元素个位数的个数,循环一次后求十位,循环两次后......
            {
                int digit = (data[i]/p) % 10;
                count[digit]++;
            }
            for(int i=1;i<n;i++)//count数组用于记录data数组元素要放在temp数组的位置。假设个位为1的数有两个,个位为2的数有三个,那么个位为1的数分别放在temp[0]和temp[1],个位数为2的则放在temp[2],temp[3],temp[4],以此类推
            {
                count[i]+=count[i-1];
            }
            for(int i=n-1;i>=0;i--)//将data数组元素按位分别放入temp数组中
            {
                int digit = (data[i]/p)%10;
                temp[count[digit] - 1] = data[i];
                count[digit]--;
            }
            for(int i=0;i<n;i++)//再把按位放好的temp数组元素放回data数组中
            {
                data[i] = temp[i];
                cout<<data[i]<<" ";
            }
            cout<<endl;
            p*=10;//除数×10,新一轮循环排序更高位。
        }
    
    }
    /************************************************************/
    
    int main()
    {
    
        int a[11]={3,2,1,6,5,4,9,8,7,1};
        int b[11]={200,6,410,51,26,98,70089,852,1265,1000};
        RadixSort(b,10);
    
        cout<<endl<<"最终排序结果:";
        for(int i=0;i<10;i++)
        {
            cout<<b[i]<<" ";
        }
        cout<<endl;
        return 0;
    }

    参考文献

    全部动态图片以及部分文字转载于菜鸟教程网站:https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

  • 相关阅读:
    Jmeter分离登录事务的另一种方式
    数据驱动 vs 关键字驱动:对搭建UI自动化测试框架的探索
    使用jmeter往指定文件中插入一定数量的数据
    JMeter 各组件介绍以及用法
    JVM(2) Java内存溢出异常
    JVM(1) Java内存区域
    OptimalSolution(1)--递归和动态规划(4)其他问题
    MySQL开发篇(5)索引、视图、触发器、SQL中的安全问题、SQL Mode、
    OptimalSolution(1)--递归和动态规划(3)数组和字符串问题
    OptimalSolution(1)--递归和动态规划(2)矩阵的最小路径和与换钱的最少货币数问题
  • 原文地址:https://www.cnblogs.com/Romantic-Chopin/p/13556765.html
Copyright © 2011-2022 走看看