冒泡排序以及改进

关于排序术语:

内排序:排序数据放置在内存中,排序操作在内存中进行

外排序:排序数据放置在磁盘中,通过磁盘和内存进行的数据传输进行排序操作

时间复杂度:算法执行所消耗的时间

空间复杂度:运行完一个程序所需内存的大小

冒泡排序

 1 function bubbleSort(arr) {
 2     // 记录传入数组的长度
 3     let len = arr.length
 4     let temp = 0
 5     // 外循环:
 6     for (let i = 0; i < len; i++) {
 7       // 内循环:
 8       for (let j = 0; j < len - 1 - i; j++) {
 9         // 相邻元素元素两两对比,如果前面的数大于后面的数,则进行位置互换
10         // 这里假定一个例子: 此刻 [..., 5, 3, ...]
11         // arr[j] = 5
12         // arr[j + 1] = 3
13         if (arr[j] > arr[j + 1]) {
14           // 位置互换
15
16           // 临时变量,将arr[j + 1] 即3存储起来,temp = 3
17           temp = arr[j + 1]
18
19           // 对arr[j + 1]进行赋值,变为前面的数值arr[j],即 arr[j + 1] = 5
20           arr[j + 1] = arr[j]
21
22           // 最后将前面的arr[j]设置为临时变量存起来的数值3,arr[j] = 3
23           arr[j] = temp
24         }
25         // 此刻,数组变成: [..., 3, 5, ...]
26       }
27       // 关于上面 j < len - 1 - i
28       // 例子:
29       // [3, 2, 5, 9, 4], length = 5
30       // 外循环第一遍
31       // 开始[3, 2, 5, 9, 4], 第1次, j = 0, arr[j] = 3, arr[j+1] = 2, 3 > 2, true ,  变动 => [2, 3, 5, 9, 4]
32       // 开始[2, 3, 5, 9, 4], 第2次, j = 1, arr[j] = 3, arr[j+1] = 5, 3 > 5, false , 不变 => [2, 3, 5, 9, 4]
33       // 开始[2, 3, 5, 9, 4], 第3次, j = 2, arr[j] = 5, arr[j+1] = 9, 5 > 9, false , 不变 => [2, 3, 5, 9, 4]
34       // 开始[2, 3, 5, 9, 4], 第3次, j = 3, arr[j] = 9, arr[j+1] = 4, 9 > 4, true ,  变动 => [2, 3, 5, 4, 9]
35
36       // 开始[2, 3, 5, 4, 9],第5次,j = 4, arr[j] = 9, arr[j + 1] = undefined,9 > ?
37       // 到达第5次,只有arr[j],但是没有arr[j + 1],所以这一步没有意义,因此这是len - 1 的理由
38
39       // 可以看到,外循环第一遍之后,会把数组中的最大数即9,推到数组最后一位
40       // 因为外循环第二遍的时候,数组[2, 3, 5, 9, 4]已经没有必要把最后一位9加入排序操作
41       // i = 0 外循环第一遍还没有开始排序,所以可排序长度: - 0
42       // i = 1 外循环第二遍开始排序了一位,所以可排序长度: - 1
43       // 这便是len - 1 - i的理由
44     }
45     // 最后返回处理完的数组
46     return arr
47 }
48 let arr = [3, 2, 5, 9, 4]
49 console.log(bubbleSort(arr)) // [2, 3, 4, 5, 9]

改进冒泡一:通过记录交换位置排序

 1 function bubbleSortByPos(arr) {
 2     // 初始时的长度需要 - 1,
 3     // 比如数组有5个数据 for循环对比时 arr[4]即是最后一个数据
 4     // 没有对比的需要,所以需要长度 - 1, 使得最后一次是a[3]与a[4]对比
 5     let len = arr.length - 1
 6     let temp = 0
 7     // while循环
 8     while(len > 0) {
 9         // 每次循环,交换位置初始值都是从0开始
10         let pos = 0
11         // 内循环
12         for (let j = 0; j < len; j++) {
13             // 相邻元素两两对比,如果前面的数大于后面的数,则位置进行互换
14             // 这里假定一个例子:此刻[..., 5, 3, ...]
15             // arr[j] = 5
16             // aarr[j+1] = 3
17             if (arr[j] > arr[j+1]) {
18                 // 当满足前面的数大于后面的数这个条件时,记录下当前的交换位置
19                 pos = j
20
21                 // 位置交互
22                 // 声明一个temp临时变量,将后面的数arr[j+1]即3存起来:temp=3
23                 temp = arr[j+1]
24
25                 // 对后面的数arr[j+1]进行赋值,变为前面的数值arr[j]: arr[j+1] = 5
26                 arr[j+1] = arr[j]
27
28                 // 最后将前面的数值arr[j]设置为临时变量存储起来的数值5: arr[j] = 3
29                 arr[j] = temp
30             }
31             // 此刻,数组变成:[..., 3, 5, ...]
32         }
33         // 本次for循环之后,可以得到本次for循环最终的交换位置pos,
34         // 该交换位置(不包含该位置)后面的都是排序好的,
35         // 所以该pos的值即是下一个for循环开始时,
36         // 该数组的截断点,截断点之前的数据都要再一次参与排序
37         len = pos
38
39         // 例子:
40         // [5, 4, 6, 2, 7, 8, 9], length = 7
41         // while循环
42         // for循环
43         // 开始[5, 4, 6, 2, 7, 8, 9], 第1次, j = 0, arr[j] = 5, arr[j+1] = 4, 5 > 4, true , 变动 => [4, 5, 6, 2, 7, 8, 9]  pos = j = 0
44         // 开始[4, 5, 6, 2, 7, 8, 9], 第2次, j = 1, arr[j] = 5, arr[j+1] = 6, 5 > 6, false, 不变 => [4, 5, 6, 2, 7, 8, 9]  pos = j = 0
45         // 开始[4, 5, 6, 2, 7, 8, 9], 第3次, j = 2, arr[j] = 6, arr[j+1] = 2, 6 > 2, true , 变动 => [4, 5, 2, 6, 7, 8, 9]  pos = j = 2
46         // 开始[4, 5, 2, 6, 7, 8, 9], 第4次, j = 3, arr[j] = 6, arr[j+1] = 7, 6 > 7, false, 不变 => [4, 5, 2, 6, 7, 8, 9]  pos = j = 0
47         // 开始[4, 5, 2, 6, 7, 8, 9], 第5次, j = 4, arr[j] = 7, arr[j+1] = 8, 7 > 8, false, 不变 => [4, 5, 2, 6, 7, 8, 9]  pos = j = 0
48         // 开始[4, 5, 2, 6, 7, 8, 9], 第6次, j = 5, arr[j] = 8, arr[j+1] = 9, 8 > 9, false, 不变 => [4, 5, 2, 6, 7, 8, 9]  pos = j = 0
49
50         // 可以看到本次for循环最终交换位置为数组下标序号2,下标2后面的数据都是排序好的,所以下标2(包含)前面的数据要进入下一次排序操作
51     }
52     // 最后返回处理完的数组
53     return arr
54 }
55 let arr = [5, 4, 6, 2, 7, 8, 9]
56 console.log(bubbleSortByPos(arr)) // [2, 4, 5, 6, 7, 8, 9]

改进冒泡二:正反方向串行排序

 1 function bubbleSortByLowAndHigh(arr) {
 2     // 初始最小序号值
 3     let low = 0
 4     // 初始时的长度需要 - 1,
 5     // 比如数组有5个数据 for循环对比时 arr[4]即是最后一个数据
 6     // 没有对比的需要,所以需要长度 - 1, 使得最后一次是a[3]与a[4]对比
 7     let high = arr.length - 1
 8
 9     let temp, j
10     // while循环, 当最小序号值小于最大序号值,才继续循环,否则说明已经排序完毕
11     while(low < high) {
12         // 从上一次排序好的最小序号位置开始,从上一次排序好的最大的序号值结束,找到最大值
13         for (j = low; j < high; j++) {
14             // 相邻元素两两对比,如果前面的数大于后面的数,则位置进行互换
15             // 这里假定一个例子:此刻[..., 5, 3, ...]
16             // arr[j] = 5
17             // aarr[j+1] = 3
18             if (arr[j] > arr[j+1]) {
19                 // 位置交互
20                 // 将后面的数arr[j+1]即3存起来:temp=3
21                 temp = arr[j+1]
22                 // 对后面的数arr[j+1]进行赋值,变为前面的数值arr[j]: arr[j+1] = 5
23                 arr[j+1] = arr[j]
24                 // 最后将前面的数值arr[j]设置为临时变量存储起来的数值3: arr[j] = 3
25                 arr[j] = temp
26             }
27         }
28         // 本次for循环找到最大值,并被置换到相应的排序好后的位置,arr数组可排序数组最大序号值减1
29         high--
30
31         // 从上一次排序好的最大序号位置开始,从上一次排序好的最小的序号值结束,找到最小值
32         for (j = high; j > low; j--) {
33             // 相邻元素两两对比,如果前面的数大于后面的数,则位置进行互换
34             // 这里假定一个例子:此刻[..., 5, 3, ...]
35             // arr[j-1] = 5
36             // aarr[j] = 3
37             if (arr[j-1] > arr[j]) {
38                 // 位置交互
39                 // 将后面的数arr[j]即3存起来:temp=3
40                 temp = arr[j]
41                 // 对后面的数arr[j]进行赋值,变为前面的数值arr[j-1]: arr[j] = 5
42                 arr[j] = arr[j-1]
43                 // 最后将前面的数值arr[j-1]设置为临时变量存储起来的数值3: arr[j] = 3
44                 arr[j-1] = temp
45             }
46         }
47         // 本次for循环找到最小值,并被置换到相应的排序好后的位置,arr数组可排序数组最小序号值加1
48         low++
49
50         // 例子:
51         // [5, 4, 6, 2, 7, 9, 8], length = 7  high = length - 1 = 6
52         // while循环
53         // 第一个for循环
54         // 开始[5, 4, 6, 2, 7, 9, 8], 第1次, j = 0, arr[j] = 5, arr[j+1] = 4, 5 > 4, true , 变动 => [4, 5, 6, 2, 7, 9, 8]
55         // 开始[4, 5, 6, 2, 7, 9, 8], 第2次, j = 1, arr[j] = 5, arr[j+1] = 6, 5 > 6, false, 不变 => [4, 5, 6, 2, 7, 9, 8]
56         // 开始[4, 5, 6, 2, 7, 9, 8], 第3次, j = 2, arr[j] = 6, arr[j+1] = 2, 6 > 2, true , 变动 => [4, 5, 2, 6, 7, 9, 8]
57         // 开始[4, 5, 2, 6, 7, 9, 8], 第4次, j = 3, arr[j] = 6, arr[j+1] = 7, 6 > 7, false, 不变 => [4, 5, 2, 6, 7, 9, 8]
58         // 开始[4, 5, 2, 6, 7, 9, 8], 第5次, j = 4, arr[j] = 7, arr[j+1] = 9, 7 > 9, false, 不变 => [4, 5, 2, 6, 7, 9, 8]
59         // 开始[4, 5, 2, 6, 7, 9, 8], 第6次, j = 5, arr[j] = 9, arr[j+1] = 8, 9 > 8, true,  变动 => [4, 5, 2, 6, 7, 8, 9]
60         // 可以看到本次for循环得到最大值为9,最大序号为high = 6
61         // 此时序号为6的值为最大值,不必进入下一次排序操作,high需要减1,可排序数组数据减少一位, high--
62
63         // [4, 5, 2, 6, 7, 8], low = 0 high = 5
64         // 第二个for循环
65         // 开始[4, 5, 2, 6, 7, 8], 第1次, j = 5, arr[j-1] = 7, arr[j] = 8, 7 > 8, false, 不变 => [4, 5, 2, 6, 7, 8]
66         // 开始[4, 5, 2, 6, 7, 8], 第2次, j = 4, arr[j-1] = 6, arr[j] = 7, 6 > 7, false, 不变 => [4, 5, 2, 6, 7, 8]
67         // 开始[4, 5, 2, 6, 7, 8], 第3次, j = 3, arr[j-1] = 2, arr[j] = 6, 2 > 6, false, 不变 => [4, 5, 2, 6, 7, 8]
68         // 开始[4, 5, 2, 6, 7, 8], 第4次, j = 2, arr[j-1] = 5, arr[j] = 2, 5 > 2, true , 变动 => [4, 2, 5, 6, 7, 8]
69         // 开始[4, 2, 5, 6, 7, 8], 第5次, j = 1, arr[j-1] = 4, arr[j] = 2, 4 > 2, true , 变动 => [2, 4, 5, 6, 7, 8]
70
71         // 可以看到本次for循环得到最小值为2,最小序号为low = 0
72         // 此时序号为0的值为最小值,不必进入下一次排序操作,low需要加1,可排序数组数据减少一位, low++
73
74         // 进入下一次while循环
75     }
76     // 最后返回处理完的数组
77     return arr
78 }
79 let arr = [3,55,38,5,87,15,34,14,27,2,46,3,25,50,28]
80 console.log(bubbleSortByLowAndHigh(arr)) // [2, 3, 3, 5, 14, 15, 25, 27, 28, 34, 38, 46, 50, 55, 87]

原文地址:https://www.cnblogs.com/linjunfu/p/10664636.html

时间: 2024-10-14 16:00:33

冒泡排序以及改进的相关文章

排序算法(一)——冒泡排序及改进

冒泡排序 冒泡排序的效率很低,但是算法实现起来很简单,因此很适合作为研究排序的入门算法. 基本思想 对当前还未排好序的范围内的全部数,自上而下对相邻的俩个数依次进行比较和调整,让较大的数下沉,较小的数往上冒.即:每当俩相邻的数比较后发现他们的排序与排序的要求相反时,就将他们交换.每次遍历都可确定一个最大值放到待排数组的末尾,下次遍历,对该最大值以及它之后的元素不再排序(已经排好). java实现 public class Sort{ private int [] array; public So

冒泡排序及改进

排序算法概述 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面. 稳定性:一个排序算法是稳定的,就是当有两个相等记录的关键字R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前. 如果算法是稳定的有什么好处呢?排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用.基数排序就是这

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

冒泡排序算法需要遍历几次数组.每次遍历都要比较连续相邻的元素,如果某一对相邻元素是降序,则互换它们的值,否则,保持不变.由于较小的值像"气泡"一样逐渐浮想顶部,而较大的值沉向底部,所以叫冒泡排序. 冒泡排序的图解是: 总结一句话就是:连续比较相邻的元素,降序则呼唤.有n个数,共需要比较n-1趟,第i趟,需要比较n-i次. BubbleSort.java public class BubbleSort {//时间复杂度O(n^2) public static void display(i

冒泡排序的改进:鸡尾酒排序

鸡尾酒排序,也叫定向冒泡排序,是冒泡排序的一种改进.此算法与冒泡排序的不同处在于从低到高然后从高到低,而冒泡排序则仅从低到高去比较列里的每个元素. 它可以得到比冒泡排序稍微好一点的排序. void CocktailSort(int *a , int n){ int left = 0; int right = n - 1; while(left < right) { for(int i = left; i < right; i++) { if(a[i] > a[i+1]) swap(a,i

关于冒泡排序的改进

1.原始冒泡排序 /*冒泡排序后的顺序为从小到大*/ void Bubble_Sort(int *arr,int len)    {        int i,j,exchange;        for(i=0;i<len-1;i++)           for(j=0;j<len-i-1;j++)              if(arr[j] > arr[j+1])                {                    exchange = arr[j];   

数据结构与算法——冒泡排序(改进后)

//改进的冒泡程序#include<stdio.h>void BubbleSort(int arr[], int length); int main( ){ int i; int arr[9] = {1,1,5,7,2,4,9,6,8}; int length=sizeof(arr)/sizeof(arr[0]); BubbleSort(arr,length); for(i=0;i<length;i++) { printf("%d ",arr[i]); } } voi

js冒泡排序算法改进

// 冒泡排序算法 function bubbleSort(arr) { console.log('排序算法第0次:' + arr.join(',')); var len = arr.length; var lastIndex = 0; // 最后标记的脚标 var sortBorder = len - 1; // 需交换最大的次数 for (var i = 0; i < len - 1; i++) { let isSort = true; for (var j = 0; j < sortBo

冒泡排序的改进-鸡尾酒排序

#include <iostream> using namespace std; void Cocktail(int *arr, int size){ int tail = size - 1; for(int i = 0; i < tail;){ for(int j = tail; j > i; j--){ if(arr[j] < arr[j-1]){ int temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; } } ++i

[整理]改进的冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名. /// <summary> /// 改进的冒泡排序 /// </summary> /// <param name="array">待排序的数组&l