冒泡排序Bubble Sort

经典排序算法 — 冒泡排序Bubble Sort

原理是相邻的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,

这样一趟过去后,最大或最小的数字被交换到了最后一位,

然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子

例子:从小到大排序,

原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |

第一趟排序(外循环)

第一次两两比较6 > 2交换(内循环)

交换前状态| 6 | 2 | 4 | 1 | 5 | 9 |

交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |

第二次两两比较,6 > 4交换

交换前状态| 2 | 6 | 4 | 1 | 5 | 9 |

交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |

第三次两两比较,6 > 1交换

交换前状态| 2 | 4 | 6 | 1 | 5 | 9 |

交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |

第四次两两比较,6 > 5交换

交换前状态| 2 | 4 | 1 | 6 | 5 | 9 |

交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

第五次两两比较,6 < 9不交换

交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |

交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

第二趟排序(外循环)

第一次两两比较2 < 4不交换

交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |

交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

第二次两两比较,4 > 1交换

交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

第三次两两比较,4 < 5不交换

交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

第四次两两比较,5 < 6不交换

交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |

交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

第三趟排序(外循环)

第一次两两比较2 > 1交换

交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

第二次两两比较,2 < 4不交换

交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

第三次两两比较,4 < 5不交换

交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

第四趟排序(外循环)无交换

第五趟排序(外循环)无交换

排序完毕,输出最终结果1 2 4 5 6 9

假设:n个数 外层循环 n-1 次 内层循环(每一次外层循环) n-1-i 次

C程序 从小到大

void BubbleSort(int *array, int n)
{
    int i, j, temp = 0;

    //外层循环
    for (i=0; i<n-1; i++)
    {
        //内层循环
        for (j=0; j<n-1-i; j++)
        {
            //交换两个数的位置
            //不可以是arr[j] >= arr[j+1],因为冒泡排序是一个稳定的算法,加上=之后就不是一个稳定的算法了 
            if (array[j] > array[j+1])
            {
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            }
        }
    }
}

注意:上面的冒泡排序不是一个优秀的算法
试想,如果要排列的数列为 1、2、3、4、5、8、9、7、6
只需要比较4趟就可以。但是上面的算法中却比较了9次。造成效率低下。也就是说在4趟比较完之后就意味着排序就已经排好了。可以结束了。认识到这一点就可以对程序进行改进。
改进:
在算法中设置一个flag变量。当flag为1时说明本趟排序中仍有元素要交换,因此还需要下一趟的比较。当flag为0时,说明本趟排序中已经木有要交换的元素,只有元素的比较,说明已经排好序了,只比较不交换说明已经排好序。排序就结束了。

改进后的程序

void BubbleSort(int array[], int n)
{
    int i, j;
    int flag = 0;

    for (i=0; i<n-1 && flag == 1; i++)
    {
        flag = 0;

        for (j=0; j<n-1-i; j++)
        {
            //在这里引入一个新的交换两个数的方法,仅限于交换两个整数
            if (array[j] > array[j+1])
            {
                array[j] = array[j]^array[j+1];
                array[j+1] = array[j]^array[j+1];
                array[j] = array[j]^array[j+1];

                //发生数据交换就把flag置1
                flag = 1;
            }
        }   
        //本趟排序未发生交换,则说明之前的都是已经有序的,则可以提前结束算法
        if (flag == 1)
            return;
    }
}

你可能感兴趣的:(冒泡排序,排序算法)