图文并茂排序与算法总结

总结下常用的排序算法,方便以后查阅。

常见排序算法:冒泡排序、选择排序、插入排序、壳(shell)排序、合并排序、快速排序、堆排序。

要选择合适的算法,需考虑的因素:执行时间、存储空间和编程工作。

1、选择排序

具有二次方程增长阶,近适用于小列表排序。

通过列表反复扫描,每次扫描选择一项,然后将这一项移动到列表中正确的位置。

选择排序总比较次数=(n-1)+(n-2)+(n-3)+...+3+2+1

         =n(n-1)/2

n(n-1)/2是O(n^2)阶的级,所以选择排序是阶O(n^2)的算法。

//外循环控制行(循环比较次数)
 for (int i = 0; i < arr.length-1; i++) {
      //内循环控制列,前后两个比较
      for (int j = i+1; j < arr.length; j++) {
           if(arr[i]>arr[j]){
              int temp=arr[i];
              arr[i]=arr[j];
              arr[j]=temp;
            }
       }
 }

2、冒泡算法

相邻两个元素进行比较,如果符合条件就换位。

冒泡排序总比较次数=(n-1)+(n-2)+(n-3)+...+3+2+1

         =n(n-1)/2

n(n-1)/2是O(n^2)阶的级,所以冒泡排序是阶O(n^2)的算法。

//最后一个元素不需要比较
for (int i = 0; i < arr.length-1; i++) {
    //-i:让每次比较的元素减少;-1避免下标越界,即当j=4时,j+1就越界了
    for (int j = 0; j < arr.length-i-1; j++) {
        if(arr[j]>arr[j+1]){
           int temp=arr[j];
           arr[j]=arr[j+1];
           arr[j+1]=temp;
         }
    }}

3、快速排序

基本思想:

(1)先从数列中取出一个数作为基准数(一般取区间第一个数)

(2)区分过程,将比这个数大的数全放在它的右边,小于或等于它的数放到它的左边。

(3)再对各区间重复第二步,直到各区间只有一个数。

这里的例子我们用挖坑填数发来说明:

再对a[0-4]和a[6-9]这两个子区间重复上述步骤就可以了,先从后向前找,再从前向后找。

对挖坑填数进行总结:

1. i=l,j=r,将基准数挖出形成第一个坑a[i];

2. j--由后向前找比它小的数,找到后挖出此数,填前一个坑a[i]中;

3. i++由前向后找比它大的数,找到后也挖出次数填到前一个坑a[j]中。

4. 在重复执行2,3两步,直到i==j,将基准数填入a[i]中。

void quick_sort(int s[],int l,int r){
        if(l<r){
            int i=l,j=r,x=s[l];
            while(i<j){
                while(i<j&&s[j]>=x){j--;}//从右向左找第一个小于x的数
                if(i<j){s[i++]=s[j];}
                while(i<j&&s[i]<x){i++;}//从左到右找第一个大于等于x的数
                if(i<j){s[j--]=s[j];}
            }
            s[i]=x;
            quick_sort(s,l,i-1);//递归
            quick_sort(s,i-1,r);
        }
    }

4、插入排序

具有二次方程增长阶,仅用于小列表排序。

如果需要排序的列表几乎已经排序,则插入排序比冒泡排序和选择排序更有效率。

插入排序执行不同次数的比较,这取决于最初的元素分阶,当元素已经处于排序阶,则插入排序需要进行极少比较。

需将列表分为两个子列表,即排序和未排序。

排序列表                                                   未排序列表

for (int i = 0; i < arr.length; i++) {//假设第一个元素放到了正确的位置上,这样仅需遍历1~n-1
            int j=i;
            int target=arr[i];
            while(j>0&&target<arr[j-1]){
                arr[j]=arr[j-1];
                j--;
            }
            arr[j]=target;
        }

最佳用例效率:O(n),当列表已经被排序时,产生最佳用例。

最差用例效率:O(n^2),当列表反向顺序排列时,产生最差用例。

5.壳(Shell)排序

通过若干位置的距离形成多个子列表分隔元素并进行比较来改进插入排序算法。对每个子列表应用插入排序时元素朝着其正确的位置移动,减少了比较次数。

-------选择分隔组中元素的距离以形成多个子列表。(这里为3)

-------对每个子列表应用插入排序使元素朝着其正确的位置移动。

6.堆排序

堆排序与快速排序、归并排序一样都是时间复杂度为O(nlogn)的几种常见排序。

若将堆视为一个完全二叉树,则堆的含义为:完全二叉树中有非叶结点(ri)均不大于(后不小于)其左孩子的值(r(2)i),右孩子的值(r(2i+1))。

堆定义是:n个关键字序列k1,k2,k3,...kn称为堆,当且仅当该序列满足如下性质:

(1)ki<=k(2i)且ki<=k(2i+1)或

(2)ki>=k(2i)且ki>=k(2i+1)  (1<=i<=[n/2])

即孩子结点>=双亲结点   或  孩子结点<=双亲结点

eg:{6,8,7,9,01,3,2,4,5}说明采用堆排序方法进行排序的过程。

输出:9,8,7,6,5,4,3,2,1,0

7.归并排序

多次将若干个已经排序好的有序表合并成一个有序表。直接将两个表合并的归并成为二路归并。

eg:{18,2,20,34,12,32,6,16}说明归并排序方法进行排序的过程。

时间特性说明:

时间复杂度O(nlogn):快速、堆、归并排序。快速最快,在n较大时,归并较堆更快。

时间复杂度为O(n^2):插入、冒泡、选择排序。插入最常用,尤其基本有序时,选择记录移动次数最少。

当待排序记录有序时:插入和冒泡可达到O(n),快速蜕化到O(n^2).

选择、堆、归并排序的时间特性不随关键字分布而改变。

时间: 2024-08-24 15:59:43

图文并茂排序与算法总结的相关文章

图文并茂排序与算法

图文并茂排序与算法总结 转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5094764.html 总结下常用的排序算法,方便以后查阅. 常见排序算法:冒泡排序.选择排序.插入排序.壳(shell)排序.合并排序.快速排序.堆排序. 要选择合适的算法,需考虑的因素:执行时间.存储空间和编程工作. 1.选择排序 具有二次方程增长阶,近适用于小列表排序. 通过列表反复扫描,每次扫描选择一项,然后将这一项移动到列表中正确的位置. 选择排序总比较次数=(n-1)+(

Java数据结构 遍历 排序 查找 算法实现

1. 遍历算法(遍历二叉树6种方法) 1.1. 概述 遍历算法针对二叉树而言的,主要有先序.中序.后序三种遍历顺序,三种顺序又分别有递归和常规算法,二叉树遍历的主要思想是:遍历左子树,遍历右子树,访问根节点,由这三者的遍历顺序来确定是先序.中序还是后序.下面只要求掌握递归遍历算法,常规遍历算法见附录一. 1.2. 先序遍历算法 遍历顺序:访问根节点,遍历左子树,遍历右子树.代码如下: void preOrder(BinaryTreeNode bt) { if (bt == null)// 如果当

对大对象进行排序的算法

快速排序就是快速排序,谢尔排序就是谢尔排序.然而,直接应用基于这些算法的函数模板时,如果要排序的Comparable对象很大的话,有时效率会很低.问题就在于.问题就在于重新排列Comparable对象时,进行太多复制Comparable对象的工作.如果Comparable对象很大而且难于复制的话,其代价也会很高. 一般来说,这个问题的解决方案很简单:生成一个指向Comparable的指针数组,然后重新排列这些指针.一旦确定了元素应该在的位置,就可以直接将该元素放在相应的位置上,而不必进行过多的中

C/C++ 排序&amp;&amp;查找算法(面试)

一.排序 1.冒泡排序 1 void BubbleSort(int array[],int n) 2 { 3 int i=0; 4 int j=0; 5 int temp=0; 6 int flag = 0; 7 for(i=0;i<n - 1 ;i++) /*外循环控制排序的总趟数*/ 8 { 9 flag = 0; /*本趟排序开始前,交换标志应为假*/ 10 for(j=n-1;j > i;j--) /*内循环控制一趟排序的进行*/ 11 { 12 if(array[j] < ar

拓扑排序(算法竞赛入门经典)

拓扑排序的定义: 把每个变量看成一个点,”小于“或者”先后“关系看成有向边,则我们得到一个有向图.这样我们的任务实际上是把一个图的所有节点排序,使每一条有向边的(u,v)对应的u都排在v之前,在图论中,我们称之为拓扑排序.不难发现,如果一个有向图里存在回路,则不存在拓扑排序(如果设置一个标志数组,我们可以发现回路中的点一直处于正在被访问状态,这可以作为拓扑排序的结束条件). 我们先看一个样例: 下面我们用邻接矩阵存储这张图:   0 1 2 3 0 0 1 1 1 1 0 0 1 1 2 0 0

排序——堆排序算法

堆排序利用的完全二叉树这种数据结构所设计的一种算法,不过也是选择排序的一种. 堆实质上是满足如下性质的完全二叉树:k[i]<=k[2*i]&&k[i]<=k[2*i+1]或者k[i]>=k[2*i]&&k[i]>=k[2*i+1], 树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字. 堆分大顶堆和小顶堆:k[i]<=k[2*i]&&k[i]<=k[2*i+1]是小顶堆,k[i]>=k[2

C言语合并排序(兼并排序)算法及代码

合并排序也称兼并排序,其算法思惟是将待排序序列分为两局部,顺次对分得的两个局部再次运用合并排序,之后再对其停止兼并.仅从算法思惟上理解合并排序会认为很笼统,接下来就以对序列A[0], A[l]-, A[n-1]停止升序陈列来停止解说,在此采取自顶向下的完成办法,操作步调如下.(1)将所要停止的排序序列分为阁下两个局部,假如要停止排序的序列的肇端元素下标为first,最初一个元素的下标为last,那么阁下两局部之间的临界点下标mid=(first+last)/2,这两局部辨别是A[first -

数据结构——排序——冒泡排序算法

冒泡排序(Bubble Sort)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端. 冒泡排序对n个项目需要O(n2)的比较次数,且可以原地排序.尽管这个算法是最简单了解和实作的排序算法之一,但它对于少数元素之外的数列排序是很没有效率的. 冒泡排序是与插入排序拥有相等的执行时间,但是两种法在需要的交换次

产品列表页分类筛选、排序的算法实现(PHP)

一.简单的单条件查询 工作都是从简单的开始,先从最简单的单表查询开始,这个一般用在首页以及一些比较独立的页面,只需要查找几个符合条件的产品展示出来即可,可以使用分页或者不使用分页.下面这个是产品控制器 ProductController 中的一个函数,用于简单的查询,比如199元专区就可以使用 getTypeSimPro('price=199'); /**简单的筛选条件分类产品,单表查询 * @param string $sql 单表查询的SQL * @param int $countPerPa