排序算法之冒泡、插入、快排和选择排序

排序算法大全

package cn.baidu;

import java.util.Arrays;

public class SortTest {

    public static void main(String[] args) {
        int[] arr = { 2, 5, 3, 1, 4 };
        System.out.println("排序前:" + Arrays.toString(arr));
        // InsertSort.sort(arr);
        // BubbleSort.sort(arr);
        // SelectionSort.sort(arr);
        // ShellSort.sort(arr);
        // QuickSort.sort(arr);
        // MergeSort.sort(arr);
        // HeapSort.sort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }

    /*
     * 交换数组中的两个元素
     */
    public static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

 /**
     * 冒泡排序(稳定)
     * @param array

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

     算法步骤 :
        1: 比较相邻的元素.如果第一个比第二个大,就交换他们两个.
        2: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.这步做完后,最后的元素会是最大的数.
        3: 针对所有的元素重复以上的步骤,除了最后一个.
        4: 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较.

     */
    public static void bubbleSort(int[] array){
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < (array.length - 1 - i); j++) {
                if(array[j] > array[j+1]){
                    swap(array, j, j+1);
                }
            }
            System.out.println(Arrays.toString(array));
        }
    }

package cn.baidu;

/*
 * 插入排序基本思想
 * 将n个元素的数列分为已有序和无序两个部分,如插入排序过程示例下所示:   
 * {{a1},{a2,a3,a4,…,an}}   
 * {{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}}  
 * {{a1(n-1),a2(n-1) ,…},{an(n-1)}}   
 * 每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,
 * 找出插入位置,将该元素插入到有序数列的合适位置中。

 插入排序是一种罪简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,
 找到相应位置并插入.

 算法步骤 :
    1: 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是末排序序列.
    2: 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置.(如果待插入的元素与有序序列中的某个元素相等
    ,则将待插入元素插入到相等元素的后面.

 */
public class InsertSort {
    public static void sort(int[] data) {
        for (int i = 1; i < data.length; i++) {
            for (int j = i; (j > 0) && (data[j] < data[j - 1]); j--) {
                SortTest.swap(data, j, j - 1);
            }
        }

    }
}

/*
 * 选择排序基本思路:
 * 把第一个元素依次和后面的所有元素进行比较。
 * 第一次结束后,就会有最小值出现在最前面。
 * 依次类推
 选择排序(Selection sort)也是一种简单直观的排序算法

 算法步骤 :
    1: 首先在末排序序列中找到最小(最大)元素,存放到排序序列的起始位置.
    2: 再从剩余末排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾
    3: 重复第二步,直到所有元素均排序完毕.

 */
public class SelectionSort {
    public static void sort(int[] data) {
        for (int x = 0; x < data.length - 1; x++) {
            for (int y = x + 1; y < data.length; y++) {
                if (data[y] < data[x]) {
                    SortTest.swap(data, x, y);
                }
            }
        }
    }
}
  /**
     * 快速排序(不稳定): 所谓的不稳定是当两个相同的数字在数组中的时候,会出现一种情况,就是把这两个相同的数给交换了位置.
     * @param array
     快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
    快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

    算法步骤:
    1 从数列中挑出一个元素,称为 “基准”(pivot),
    2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

    递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

     */
    public static void quickSort(int[] array){
        quickSort(array, 0, array.length - 1);
    }

    private static void quickSort(int[] array, int low, int high) {
        int i = low, j = high;
        int pivot = array[(low + high)/2];//中间位置值
        while (i <= j){
            while(array[i] < pivot){
                i++;
            }
            while(array[j] > pivot){
                j--;
            }

            if(i <= j){
                swap(array, i, j);
                i++;
                j--;
            }
        }
        if(i < high){
            quickSort(array, i, high);
        }
        if(j > low){
            quickSort(array, low, j);
        }
    }

    /**
     * 交换数组值
     * @param array
     * @param i
     * @param j
     */
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
}

package com.dn.sort;

public class BinaryInsertSort {
    public static void main(String[] args) {
        int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};
        System.out.println("排序之前:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
        //二分插入排序
        sort(a);
        System.out.println();
        System.out.println("排序之后:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
//二分法插入
    private static void sort(int[] a) {
        for (int i = 0; i < a.length; i++) {
            int temp = a[i];
            int left = 0;
            int right = i-1;
            int mid = 0;
            //确定要插入的位置
            while(left<=right){
                //先获取中间位置
                mid = (left+right)/2;
                if(temp<a[mid]){
                    //如果值比中间值小,让right左移到中间下标-1
                    right = mid-1;
                }else{
                    //如果值比中间值大,让left右移到中间下标+1
                    left = mid+1;
                }
            }
            for (int j = i-1; j >= left; j--) {
                //以左下标为标准,在左位置前插入该数据,左及左后边全部后移
                a[j+1] = a[j];
            }
            if(left != i){
                //左位置插入该数据
                a[left] = temp;
            }
        }
    }
}

package com.dn.sort;

public class InsertSort {
/**
 * 直接插入排序
 * @param args
 */
        public static void main(String[] args) {
            int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};
            System.out.println("排序之前:");
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i]+" ");
            }
            //直接插入排序
            for (int i = 1; i < a.length; i++) {
                //待插入元素
                int temp = a[i];
                int j;
                for (j = i-1; j>=0; j--) {
                    //将大于temp的往后移动一位
                    if(a[j]>temp){
                        a[j+1] = a[j];
                    }else{
                        break;
                    }
                }
                a[j+1] = temp;//插入进来
            }
            System.out.println();
            System.out.println("排序之后:");
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i]+" ");
            }
        }
}

原文地址:https://www.cnblogs.com/haizai/p/11742845.html

时间: 2024-11-05 05:03:00

排序算法之冒泡、插入、快排和选择排序的相关文章

排序算法之冒泡和快排

冒泡排序: 顾名思义:参与排序的数据就像水中的气泡慢慢浮出水面一样"浮"到数列顶端. 冒泡排序要点: 1.  两层循环,外层循环控制走访数列重复进行的次数,内层循环进行数据的比较.交换,是数据"上浮". 2.  内层循环是相邻的数据进行比较. C语言代码实现: // 冒泡排序 void sort_bubble(int n){ int i,j; for(i=0;i<n-1;i++){ for(j=0;j<n-1-i;j++){ if(arr[j]>a

排序算法第一篇(简单桶排、选择排序、冒泡排序、快速排序)

简单桶排序 1 /** 2 * @author: 攻城狮小白 3 * @creationTime:2017年11月24日 下午10:37:59 4 * @description: 桶排序(这个不是真正的桶排,真正的桶排比这个稍微复杂些.但是是桶排的思想,就叫它简单桶排吧) 5 * @questionDesc:一个班上有6名同学,考试成绩如下arr数组(满分10分),如何快速将学生成绩从小到大排列? 6 */ 7 public class BucketSortDemo { 8 public voi

排序算法-冒泡——插入——快排

冒泡排序,往两个方向泡,一个往小泡,一个网大泡 #include<stdio.h> #include<stdlib.h> #include<time.h> void bubble_sort(int *a,int n){ int temp; for(int i=0;i<n;i++) for(int j=0;j<n-i-1;j++){ if(a[j]>a[j+1]){ temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } } v

图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序

图形化排序算法比较:快速排序.插入排序.选择排序.冒泡排序

总结4种常用排序(快排、选择排序、冒泡排序、插入排序)

一. 选择排序 概念理解: 在一个长度为3的数组中,在第一趟遍历3个数据,找出其中最小的数值与第一个元素交换: 第二趟遍历2个数据,找出其中最小的元素与第一个数交换(注意:这里的第一个数是指遍历的第一个数,实质上是数组的第二个数) 而第三趟则是和自己比较,位置还是原来的位置 复杂度: 平均时间复杂度:O(n^2) 例子: //选择排序 function selectionSortFn(arr){ console.log('原数组:['+ arr + ']') for (var i = 0; i

经典(java版)排序算法的分析及实现之三简单选择排序

选择排序-简单选择排序 选择排序的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子系列的最后,直到全部记录排序完毕.简单选择排序也叫直接选择排序. 基本算法: 将给定待排序序列A[0....n],第一次从A[0]~A[n-1]中选取最小值,与A[0]交换,第二次从A[1]~A[n-1]中选取最小值,与A[1]交换,....,第i次从A[i-1]~A[n-1]中选取最小值,与A[i-1]交换,.....,第n-1次从A[n-2]~A[n-1]中选取最小值,与A[n-2]

(九)数据结构之简单排序算法实现:冒泡排序、插入排序和选择排序

d59FG8075P7伊http://www.zcool.com.cn/collection/ZMTg2NTU2NjQ=.html 312V畏蝗淤ZP哦睬http://www.zcool.com.cn/collection/ZMTg2NTU4NDQ=.html f衷4i82419s搪褂压8http://www.zcool.com.cn/collection/ZMTg2NTU4Njg=.html 75抖0瞪4豪c练偃62诵付http://www.zcool.com.cn/collection/ZM

算法导论学习之快排+各种排序算法时间复杂度总结

快排是一种最常用的排序算法,因为其平均的时间复杂度是nlgn,并且其中的常数因子比较小. 一.快速排序 快排和合并排序一样都是基于分治的排序算法;快排的分治如下: 分解:对区间A[p,r]进行分解,返回q,使得A[p–q-1]都不大于A[q] A[q+1,r]都大于A[q]; 求解:对上面得到的区间继续递归进行快排 合并:因为快排是原地排序,所以不需要特别的合并 从上可以看出最重要的就是分解函数,其按关键值将数组划分成3部分,其具体实现的过程见代码注释. 我们一般取数组的最后一个元素作为划分比较

Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排序.快速排序(重点).堆排序.归并排序等等.看下图: 给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78} 一.直接插入排序(内部排序.O(n2).稳定) 原理:从待排序的数中选出一个来,插入到前面的合适位置. [java] view plain copy