冒泡排序的终极改进优化

1、排序方法

将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。

(1)初始

     R[1..n]为无序区。

(2)第一趟扫描

     从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比较(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);对于每对气泡(R[j+1],R[j]),若R[j+1].key<R[j].key,则交换R[j+1]和R[j]的内容。

 第一趟扫描完毕时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。

(3)第二趟扫描

     扫描R[2..n]。扫描完毕时,"次轻"的气泡飘浮到R[2]的位置上……

 最后,经过n-1 趟扫描可得到有序区R[1..n]

注意:

     第i趟扫描时,R[1..i-1]和R[i..n]分别为当前的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描完毕时,该区中最轻气泡飘浮到顶部位置R[i]上,结果是R[1..i]变为新的有序区。

2、冒泡排序过程动画演示

https://www.erdangjiade.com/jquery/75/7559/demo/

3. 传统实现

package main

import "fmt"

func buble(a []int) []int {
    l := len(a)
    fmt.Println("inputed ", a, " len ", l)
    last := l - 1
    tmp := 0
    for i := l; i >= 0; i-- {
        for j := 0; j < last; j++ {
            if a[j] > a[j+1] {
                tmp = a[j]
                a[j] = a[j+1]
                a[j+1] = tmp
            }
        }
    }
    return a
}
func main() {
    a := []int{3, 7, 8, 11, 99}
    fmt.Println("len ", len(a), buble(a))
    a = []int{3, 7, 1, 4, 8, 2, 5, 11, 99, 7}
    fmt.Println("len ", len(a), buble(a))
}
inputed  [3 7 8 11 99]  len  5
len  5 [3 7 8 11 99]
inputed  [3 7 1 4 8 2 5 11 99 7]  len  10
len  10 [1 2 3 4 5 7 7 8 11 99]

改进后:

package main

import "fmt"

func buble(a []int) []int {
    l := len(a)
    fmt.Println("inputed ", a, " len ", l)
    tmp := 0
    pos := 0
    last := l - 1
    for i := l; i >= 0; i-- {
        swap := 0 //如果一趟循环没有发生过交换, 说明啥? 那就是数组已经有序了,啥也不用做
        for j := 0; j < last; j++ {
            if a[j] > a[j+1] {
                swap = 1
                pos = j //最后一次交换发生时,那么后面的数组肯定是有序了,前面的数据则可能是无序的,所以记录这个位置,下次直接对比pos前面的
数即可,这就大大减少对比次数了
          tmp = a[j]
                a[j] = a[j+1]
                a[j+1] = tmp
            }
        }
        last = pos
        if swap == 0 {//有序了,直接返回
            return a
        }
    }
    return a
}
func main() {
    a := []int{3, 7, 8, 11, 99}
    fmt.Println("len ", len(a), buble(a))
    a = []int{3, 7, 1, 4, 8, 2, 5, 11, 99, 7}
    fmt.Println("len ", len(a), buble(a))
}
inputed  [3 7 8 11 99]  len  5
len  5 [3 7 8 11 99]
inputed  [3 7 1 4 8 2 5 11 99 7]  len  10
len  10 [1 2 3 4 5 7 7 8 11 99]

  

如果你有更好的算法,欢迎评补充!!

原文地址:https://www.cnblogs.com/sunsky303/p/11526604.html

时间: 2024-10-11 19:23:27

冒泡排序的终极改进优化的相关文章

【总结】冒泡排序及冒泡排序的两种优化

------------------------------------------------------------------------------------------------------ 冒泡排序(bubble sort)算法的运作如下:从前往后一次比较相邻的两个元素,如果第二个比第一个元素小,则交换这两个元素,一直到与最后一个元素比较完成,这样最大的元素就放到了最后:这样重复比较(n-1)次即可完成排序. -----------------------------------

数据结构之--冒泡排序算法及改进

冒泡排序,是我们学习数据结构第一个排序算法,也是一种最常见和简单的排序算法. 排序原理: 我们把一个数组从左到右依次两两元素比较,比较完成一趟后,能确定最大(最小)值,放在最右边(最左边): 剩下的元素重复上述步骤,直到整个数组有序. 该算法时间复杂度一般为n2  . java实现代码如下: public class BubbleSort { public static void swap(int[] array, int a, int b) { array[a] = array[a] ^ ar

冒泡排序及两种优化方式

冒泡排序是最常用的小型数据排序方式,下面是用C语言实现的,及其两种优化方式. 第一种优化方式是设置一个标记位来标记是否发生了交换,如果没有发生交换就提前结束: 第二种优化方式是记录最后放生交换的位置,作为下一趟比较结束的位置. #include <stdio.h> /* * 打印数组 * */ void printArray(int arr[], int n) { int i = 0; for (i = 0; i < n; ++i) { printf("%d ", a

冒泡排序及尝试改进

冒泡排序是一种交换排序思想,既两两比较待排序记录的关键字(值),发现两个记录的次序(大小)相反时进行交换,直到所有记录都满足排序要求. 该算法的平均时间复杂度为O(n2),冒泡排序算法时有几个可以缩短操作的方法: 如果一次排序比较过程中没有发生记录位置交换,即可停止排序操作: 如果一次排序比较过程中发生了记录位置交换,则最后一次记录交换的位置,可作为下一次排序比较遍历的停止位置,因为该位置之前的数据都是有序的: 冒泡排序具有不对称性,比如进行从小到大排序,当原序列最大数排在首位,尽管剩余数已经按

C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 角色权限的配置页面改进优化

往往开发的人不是维护的人,开发的单位不是维护的单位.信息的畅通沟通交流很多时候会有打折.扭曲.甚至是容易得到歪解.配置错业务操作权限.为了防止发生没必要的麻烦,甚至是发生重大错误,我们的软件需要不断换位思考,不是只是功能实现了就可以了.是否实现得最优. 原来的权限设置页面,虽然也都能完成基本工作,但是有几个缺点: 1:这个权限指向的url是多少?看不清楚.看不方便.2:这个权限是谁设置的?什么时候创建的?3:这个权限的主意事项是什么?配置时需要注意什么?看不到.4:更深入的需求.是谁赋予的权限?

冒泡排序的三种优化

传统的冒泡排序完全可以满足我们最基本的需求,但是也仅仅是最简单的需求,这种简单的两个for循环不加任何的判断语句的形式注定它只能是一种效率最低的算法. 我们先贴一个传统的实现方式,之后的三个优化全部建立在函数排序所使用的消耗上,这也是我们优化一切算法的根本路径. void BubbleSort(int* arr,int size) { assert(arr&&size); if(size==1) return; for(int i=0;i<size-1;i++) { for(int

Java_冒泡排序_原理及优化

冒泡排序及其优化 一.原理及优化原理 1.原理讲解 冒泡排序即:第一个数与第二个数进行比较,如果满足条件位置不变,再把第二个数与第三个数进行比较.不满足条件则替换位置,再把第二个数与第三个数进行比较,以此类推,执行完为一个趟,趟数等于比较的个数减一. 2.冒泡排序原理图示:(以98765序列为例,排序结果从小到大) 3.冒泡排序优化 优化版:每一次减少一次循环(即红色部分不需要在进行比较) 4.冒泡排序最终版 最终版:每一趟减少一次循环(删除线不需要再执行) 二.实现代码 1.冒泡排序实现主要代

冒泡排序的实现及优化和变形

1.概述 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端.在一般面试中也是最容易碰到的排序算法. 算法描述 比较相邻的元素.如果第一个比第二个大,就交换它们两个: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数: 针对所有的元素重复以上的步骤,除了

冒泡排序以及冒牌排序优化算法

冒泡排序是最常用的排序算法,在笔试中也非常常见,能手写出冒泡排序算法可以说是基本的素养. 算法重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,这样越大的元素会经由交换慢慢“浮”到数列的顶端. 时间复杂度 算法稳定性 冒泡排序就是把小的元素往前调或者把大的元素往后调.比较是相邻的两个元素比较,交换也发生在这两个元素之间.所以,如果两个元素相等,是不会再交换的:如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺