常用排序算法总结(基于算法 第四版)

1.初级排序算法

1.1我们关注的主要对象为重拍数组元素的算法。,其中每个元素有个主键,将主键按照某种方式排列。在java中元素通常都是对象,对主键描述往往通过comparable接口。

一般排序模板

public class Example{
    public static void sort(Comparable[] a)
        {.......}
    private static boolean less(Comparable v,Comparable w)
        { return v.compareTo(w)<0;}
    private static void each(Comparable[] a,int i, int j)
        { Comparable t=a[i]; a[i]=a[j]; a[j]=t;}
    private static void show(Comparable[] a)
        {//在单行中打印数组
          for(int i=0; i<a.length; i++)
               StdOut.print(a[i]+ ";");
               StdOut.println();
         }
    public static boolean isSorted(Comparable[] a)
        {//检测是否有序
          for(int i=1; i<a.length; i++)
             if(less(a[i],a[i-1])) return false;
              return true;
        }
    public static void main(String[] args)
        {//从标准输入读取字符串,排序后输出
          String[] a=In.readStrings();
          sort(a);
          assert isSorted(a);
          show(a);
        }
}

在java中一般是靠这个比较,即V<W返回负值(-1),返回0;V=W,;V>W,返回正值(1)

 private static boolean less(Comparable v,Comparable w)
        { return v.compareTo(w)<0;}

1.2 Selection选择排序

即先找出最小元素调整位置,往复。

特点:

对于长度为N的数组,选择排序需要大约N^2/2次比较和N次交换,运行时间和输入无关,数据移动最少

public class Selection {
    public static void sort(Comparable[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            int min = i;
            for (int j = i; j < n; j++)
                if (less(a[min], a[i])) min = j;
            exch(a, i, min);
        }
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static void show(Comparable[] a) {//在单行中打印数组
        for (int i = 0; i < a.length; i++)
            StdOut.print(a[i] + ";");
        StdOut.println();

    }

    private static boolean isSorted(Comparable[] a) {//检测是否有序
        for (int i = 1; i < a.length; i++)
            if (less(a[i], a[i - 1])) return false;
        return true;

    }

    public static void main(String[] args) {//从标准输入读取字符串,排序后输出
        String[] a = StdIn.readAllStrings();
        sort(a);
        assert isSorted(a);
        show(a);
    }
}

其中比较交换是

for (int j = i; j < n; j++)
                if (less(a[min], a[i])) min = j;
            exch(a, i, min);执行顺序

1.3 Insertion(插入排序)对随机排列的长度为N且主键不重复的数组,平均情况下插入排序需要~N^2/4比较及~N^2/4次交换。最坏情况需要~N^2/2比较及~N^2/2次交换,最好为N-1次比较及0次交换
public class Insertion {
    public static void sort(Comparable[] a) {
        int N = a.length;
        for (int i = 1; i < N; i++) {
            for (int j = i; j > 0 && less(a[j], a[j - 1]); j--)
                exch(a, j, j - 1);
        }
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static void show(Comparable[] a) {//在单行中打印数组
        for (int i = 0; i < a.length; i++)
            StdOut.print(a[i] + ";");
        StdOut.println();

    }

    private static boolean isSorted(Comparable[] a) {//检测是否有序
        for (int i = 1; i < a.length; i++)
            if (less(a[i], a[i - 1])) return false;
        return true;

    }

    public static void main(String[] args) {//从标准输入读取字符串,排序后输出
        String[] a = StdIn.readAllStrings();
        sort(a);
        assert isSorted(a);
        show(a);
    }
}

插入排序需要的交换操作和数组倒置数量相同,需要比较次数大于等于倒置数量,小于等于倒置数量加上数组大小再减一。

执行顺序

1.4比较排序算法

public class sortCompare {
public static double time(String alg, Double[] a) {
        Stopwatch timer = new Stopwatch();
        if (alg.equals("Insersion")) Insertion.sort(a);
        if (alg.equals("Selection")) Selection.sort(a);        //其他排序。。。
        else throw new IllegalArgumentException("Invalid algorithm: " + alg);
        return timer.elapsedTime();
    }

    public static double timeRandomInput(String alg, int N, int T) {
        //
        double total = 0.0;
        Double[] a = new Double[N];
        for (int t = 0; t < T; t++) {
            for (int i = 0; i < N; i++)
                a[i] = StdRandom.uniform();
            total += time(alg, a);
        }
        return total;
    }

    public static void main(String[] args) {
        String alg1 = args[0];
        String alg2 = args[1];
        int N = Integer.parseInt(args[2]);
        int T = Integer.parseInt(args[3]);
        double t1 = timeRandomInput(alg1, N, T);
        double t2 = timeRandomInput(alg2, N, T);
        StdOut.printf("For %d random Double\n  %s id", N, alg1);
        StdOut.printf(" %.1f times faster than %s\\n", t2 / t1, alg2);

    }
}

1.5 Shell排序

基于插入排序的改进。当极值位于极端位置时,需要大量时间。

h有序数组

假设存在任意间隔h的元素为有序的,那么可以节省时间。

public class Shell {
    public static void sort(Comparable[] a) {
        int N = a.length;
        int h = 1;
        while (h < N / 3) h = h * 3 + 1; //1,4,13,40,121
        while (h >= 1) {
            //数组为h有序
            for (int i = h; i < N; i++) {
                for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
                    exch(a, j, j - h);
            }
            h = h / 3;
        }
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static void show(Comparable[] a) {//在单行中打印数组
        for (int i = 0; i < a.length; i++)
            StdOut.print(a[i] + ";");
        StdOut.println();

    }

    private static boolean isSorted(Comparable[] a) {//检测是否有序
        for (int i = 1; i < a.length; i++)
            if (less(a[i], a[i - 1])) return false;
        return true;

    }

    public static void main(String[] args) {//从标准输入读取字符串,排序后输出
        String[] a = StdIn.readAllStrings();
        sort(a);
        assert isSorted(a);
        show(a);
    }
}

分析h,j,i,a[x]变化趋势

SHELLSORTEXAMPLE

h=13时  j=[h,2h]

比较区间为PS|LH|EE|

h=4时,i~16,j=[h,2h] 比较一次 j=[2h,3h]比较两次 j=[3h,4h]比较三次

j=[h,2h]时

比较区间为:|LP|SH|OE|RL|

j=[2h,3h]时

比较区间为:|TLP|ESH|XOE|ARL|

j=[3h,4h]时

比较区间为:|MTLP|SESH|LXOE|EARL|

h=1,插入排序

执行顺序

可视化



原文地址:https://www.cnblogs.com/yhsing/p/12182531.html

时间: 2024-10-12 03:43:07

常用排序算法总结(基于算法 第四版)的相关文章

基于比较的常用排序算法总结

基于比较的排序算法,应该是最符合人们直觉的方法.在各种算法的技术书上,已经证明了基于比较的排序算法的时间最优复杂度为O(nlogn). 下面是几种常见的基于比较的排序算法: 1. 选择排序:这应该是最直观的排序方法.在排序n个元素时,第一次遍历,找到最小的元素,将其与第一个元素互换:第二次遍历,找到次小的元素,将其与第二个元素交换:直至剩下最后一个元素. 2. 冒泡排序:这应该是我们学到的第一种排序算法.基本思想就是,通过依次比较相邻的两个元素,如后值比前值小,则交换这两个值,小值被交换到前面,

常用排序算法小结

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 5 //the basic bubble sort 6 void maopao1(int *num,int len) 7 { 8 int i,j; 9 int temp; 10 for (i = 0; i < len-1; ++i) 11 { 12 for (j = i+1; j<len; ++j) 13 { 14 if (num[i]>num[j]) 15 { 16 t

常用排序算法的python实现和性能分析

http://www.cnblogs.com/wiki-royzhang/p/3614694.html 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整了一下,可以阶段性的留下些脚印——没办法,平时太忙,基本上没有时间写博客.面试测试开发的话,这些也许能帮得上一些. 这篇是关于排序的,把常见的排序算法和面试中经常提到的一些问题整理了一下.这里面大概有3个需要提到的问题: 虽然专业是数

常用排序算法的python实现

排序算是编程最基本的算法问题之一了,熟练掌握排序算法也能加深自己对数据结构的理解,也能提高自己的编程能力,以下为个人参考许多大神博客后对常用排序算法的学习总结. 目录: 概述 冒泡排序 直接插入排序 简单选择排序 希尔排序 堆排序 归并排序 快速排序 算法的比较与测试 参考 1. 概述 所谓排序(sorting)就是整理数据的序列,使其按照特定顺序排列的操作.排序在现实生活中(如整理书籍,表格数据等),在计算领域中(如二分查找,图论的最小生成树的Kruskal算法)均有重要意义,所以一种高效的排

常用排序算法

本篇给大家介绍几种软件工程中常用的排序算法 1. 插入排序 插入排序的基本思想就是:每次将一个待排序的记录,按其关键字大小插入到前面已经排序好的序列中,直到全部记录插入完成为止. 对于插入排序的概念以及其原理大家可以参考<排序算法的学习之路——插入排序(概念篇)> 插入排序细分可以分成三种情况. 直接插入排序——<排序算法学习之路——直接插入排序> 折半插入排序——<排序算法学习之路——折半插入排序> 表插入排序 ——<排序算法学习之路——表插入排序> 2.

转载部长一篇大作:常用排序算法之JavaScript实现

注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang1724/p/3946339.html#3037096.O(∩_∩)O~  知识产权归部长原文所有. 笔试面试经常涉及各种算法,本文简要介绍常用的一些算法,并用JavaScript实现. 1.插入排序 1)算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫

常用排序算法比较与分析

一.常用排序算法简述 下面主要从排序算法的基本概念.原理出发,分别从算法的时间复杂度.空间复杂度.算法的稳定性和速度等方面进行分析比较.依据待排序的问题大小(记录数量 n)的不同,排序过程中需要的存储器空间也不同,由此将排序算法分为两大类:[内排序].[外排序]. 内排序:指排序时数据元素全部存放在计算机的随机存储器RAM中. 外排序:待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中还需要对外存进行访问的排序过程. 先了解一下常见排序算法的分类关系(见图1-1) 图1-1 常见排

视觉直观感受7种常用排序算法

视觉直观感受若干常用排序算法 1 快速排序 介绍: 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性. 步骤: 从数列中挑出一个元素,称为 "基准"(pivo

C++常用排序算法

排序算法是一种基本并且常用的算法.由于实际工作中处理的数量巨大,所以排序算法对算法本身的速度要求很高.而一般我们所谓的算法的性能主要是指算法的复杂度,一般用O方法来表示.在后面我将给出详细的说明.  简单排序算法,后面你将看到他们的共同点是算法复杂度为O(N*N): 1.冒泡排序: #include <iostream.h> void BubbleSort(int* pData,int Count) { int iTemp; for(int i=1;i<Count;i++) { for(

Java常用排序算法实现

目录 目录 概述 插入排序 希尔排序 简单排序 堆排序 冒泡排序 快速排序 源码 概述 这里总的给出了几种常用的排序算法,也是当作复习和巩固. 插入排序 希尔排序 简单排序 堆排序 冒泡排序 快速排序 以上几个都是根据排序的原理和原则自定义实现的.对于同一个排序实际的实现过程可能有一些不同,但思想和处理方式是相同的. 插入排序 基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的.如此反复循环,直到全部