排序算法的简单实现(冒泡和快排)

排序算法

冒泡排序

原理:把相邻的元素两两比较,根据大小来交换元素的位置。

原始的冒泡排序是稳定排序。由于该排序的每一轮要遍历所以元素,轮转的次数和元素数量相当,所以时间复杂度是 O(N^2)。

java代码表达如下:

import java.util.Arrays;

public class BubbleSort{
    private static void sort(int array[]){
        int tmp = 0;
        for (int i = 0; i < array.length; i++){
            for (int j = 0; j < array.length - i - 1;j++) {
                if (array[j] > array[j+1]) {
                    tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
        }
    }

    public static void main(String[] args){
        int[] array = new int[]{5,8,6,3,9,2,1,7};
        sort(array);
        System.out.println(Arrays.toString(array));
    }
}

(使用双循环来进行排序。外部循环控制所有的回合,内部循环代表每一轮的冒泡处理,先进行元素比较,再进行元素交换。)

冒泡优化(一)

判断出数列已经有序,并且做出标记,剩下的几轮排序就可以不必执行,提早结束工作。

代码如下:

import java.util.Arrays;

public class BubbleSort{
    private static void sort(int arrray[]){
        int tmp = 0;
        for (int i = 0; i < arrray.length; i++) {
            //有序标记,每一轮的初始是true
            boolean isSorted = true;
            for (int j = 0; j < arrray.length - i - 1; j++ ) {
                if(arrray[j] > arrray[j+1]) {
                    tmp = arrray[j];
                    arrray[j] = arrray[j+1];
                    arrray[j+1] = tmp;

                    //有元素交换,所以不是有序,标记变为false
                    isSorted = false;
                }
            }
            if(isSorted){
                break;
            }
        }
    }

    public static void main(String[] args){
        int[] arrray = new int[]{5,8,6,3,9,2,1,7};
        sort(arrray);
        System.out.println(Arrays.toString(arrray));
    }
}

利用布尔变量 isSorted作为标记。如果在本轮排序中,元素有交换,则说明数列无序;如果没有元素交换,说明数列已然有序,直接跳出大循环。

冒泡优化(二)

如果元素排序前面无序,后面无序,我们可以设定排序边界,这样当遍历到有序数组时,跳出循环,结束程序。

思路:我们在每一轮排序的最后,记录下最后一次元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。

代码如下:

import java.util.Arrays;

public class BubbleSort {
    private static void sort(int array[]) {
        int tmp = 0;
        // 记录最后一次交换的位置
        int lastExchangeIndex = 0;
        // 无序数列的边界,每次比较只需要比到这里为止
        int sortBorder = array.length - 1;
        for (int i = 0; i < array.length; i++) {
            // 有序标记,每一轮的初始是true
            boolean isSorted = true;
            for (int j = 0; j < sortBorder; j++) {
                if (array[j] > array[j+1]) {
                    tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    // 有元素交换,所以不是有序,标记为false
                    isSorted = false;
                    // 把无序数列的边界更新为最后一次交换元素的位置
                    lastExchangeIndex = j;
                }
            }

            sortBorder = lastExchangeIndex;
            if (isSorted) {
                break;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = new int[]{3,4,2,1,5,6,7,8};
        sort(array);
        System.out.println(Arrays.toString(array));
    }
}

sortBorder 就是无序数列的边界。每一轮排序过程中,sortBorder 之后的元素就完全不需要比较了,肯定是有序的。

快速排序

快速排序跟冒泡排序一样,都属于交换类排序,通过采用不断的比较和移动元素来实现排序。

快速排序利用了 ”分治法“ 的思想, 通过设置基准数 key ,将比基准数大的数从前面移动到后面,比基准数小的数从后面移动到前面,将数组分为两部分,其中以 key 为中心, key 左边的数比 key 小,key 右边的数比 key 大,然后对这两部分分别重复这个排序的过程,直到整个有序。

由于采取 ”分治法“ ,我们可以很容易的得出快速排序的平均时间复杂度为:O(nlogn)

快速排序的简单实现:

import java.util.Arrays;

public class QuickSort {
    private static void quickSort(int[] a, int low, int high) {
        //1.找到递归算法的出口
        if (low > high) {
            return;
        }
        //2. 存
        int i = low;
        int j = high;
        //3. key
        int key = a[low];
        //4,完成一趟排序
        while(i < j) {
            //4.1 从右往左找到第一个小于key的数
            while(i<j && a[j] > key){
                j--;
            }
            //4.2 从左往右找到第一个大于key的数
            while (i<j && a[i] <= key) {
                i++;
            }
            //4.3 交换
            if(i < j){
                int p = a[i];
                a[i] = a[j];
                a[j] = p;
            }
        }
        //4.4 调整key的位置
        int p = a[i];
        a[i] = a[low];
        a[low] = p;
        //5. 对key左边的数快排
        quickSort(a, low, i - 1);
        //6. 对key右边的数快排
        quickSort(a, i + 1, high);
    }

    public static void quickSort(int[] a){
        if (a.length>0) {
            quickSort(a, 0, a.length - 1);
        }
    }

    public static void main(String[] args) {
        int[] a = {1,2,4,5,7,4,5,3,9,0};
        quickSort(a);
        System.out.println(Arrays.toString(a));
    }

}

原文地址:https://www.cnblogs.com/weixuqin/p/10123641.html

时间: 2024-11-03 20:46:07

排序算法的简单实现(冒泡和快排)的相关文章

Java 常用的排序算法【选择、冒泡、快排】

选择排序: 简述:从数组的第一个元素开始,依次与其他所有的元素对比,如果比自身大或小(取决于升序或降序)交换位置. ChiceSort Code 冒泡排序: 简述:比较数组中两个相邻的元素,如果前者比较大则交换位置.像啤酒杯中的气泡一样,先漂上来最大的气泡,再漂上来第二大的气泡......... BubbleSort Code 快速排序: 简述:寻找一个基准(数组中的第一个或最后一个),表的两端同时向中间扫描,小在左,大在右.然后分别从基准两边进行递归排序. QuickSortCode 原文地址

C/C++实现各类排序算法(目前实现冒泡、快排)

快速排序: void quick_sort(int a[],int low,int high) { int i=low,j=high,tmp=a[low]; //tmp存储基准元素,相当于空出一个用于调动的动态位置 if(low<high) { while(i!=j) { while(j>i&&a[j]>=tmp) j--; a[i]=a[j]; //此时a[j]空出 while(j>i&&a[i]<=tmp) i++; a[j]=a[i];

八大内部排序算法(上)-冒泡、直接插入、简单选择、快速

八大内部排序算法(上)冒泡.直接插入.简单选择.快速 排序分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 1.直接插入排序 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止. 要点:设立哨兵,作为临时存储和判断数组边界之用. 直接插入实现如下:

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

冒泡排序,往两个方向泡,一个往小泡,一个网大泡 #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

排序算法(三)冒泡、选择排序的Python实现及算法优化详解

说在前面 最近一年太忙,博客长草了.近日用Python实现了常用排序算法,供大家参考. Java版本排序算法及优化,请看以前的文章. <排序算法之简单排序(冒泡.选择.插入)> <排序算法(二)堆排序> 1.排序概念 这里不再赘述,请参看前面2篇文章 2.简单排序之冒泡法Python实现及优化 原理图 2.1.基本实现 num_list = [     [1, 9, 8, 5, 6, 7, 4, 3, 2],     [1, 2, 3, 4, 5, 6, 7, 8, 9] ] nu

C语言排序算法之简单交换法排序,直接选择排序,冒泡排序

C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 1 /*简单交换法排序 2 根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置 3 交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动 4 不稳定 5 */ 6 #include<windows.h> 7 #include<stdio.h> 8 void main(){ 9 int i,j,arr[10

最简单的两种快排----掌握思想和过程

俗话说:天下武功,无坚不破.对于算法当然也是要使用时间最快.占用空间最小的算法来实现了.下面就是最简单的两种快排(其实可以算是一种). 注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果. 总之,师傅领进门,修行在个人.奋斗把!骚年! ※冒泡排序.选择排序: 1 #include "cstdio" 2 #include "iostream" 3 using namespace st

排序算法之简单排序(冒泡、选择、插入)

1.基本概念 内部排序和外部排序 根据排序过程中,待排序的数据是否全部被放在内存中,分为两大类: 内部排序:指的是待排序的数据存放在计算机内存中进行的排序过程: 外部排序:指的是排序中要对外存储器进行访问的排序过程. 内部排序是排序的基础,在内部排序中,根据排序过程中所依据的原则可以将它们分为5类:插入排序.交换排序.选择排序.归并排序:根据排序过程的时间复杂度来分,可以分为简单排序.先进排序.冒泡排序.简单选择排序.直接插入排序就是简单排序算法. 评价排序算法优劣的标准主要是两条:一是算法的运

Java实现的各种排序算法(包括冒泡,快排等)

//堆排序 不稳定 import java.util.Arrays; public class HeapSort { public static void main(String[] args) { int[] a={49,38,65,97,76,13,27,49,78,34,12,64}; int arrayLength=a.length; //循环建堆 for(int i=0;i<arrayLength-1;i++){ //建堆 buildMaxHeap(a,arrayLength-1-i)