当前位置:编程学习 > C#/ASP.NET >>

冒泡排序法理解问题,请指教啊

static void Sort(int[] array)
        {
            int length = array.Length;
            for (int i = 0; i < length - 1; i++)
            {
                for (int j = 0; j < length - 1 - i; j++)
                {
                    if (array[j] > array[j + 1])
                    {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }

                我实在不理解第二个循环就是:for (int j = 0; j < length - 1 - i; j++),为什么还要j < length - 1 - i --------------------编程问答-------------------- n个数,第一轮排完后,最后一个数一定是最大的,所以第二轮只需要排前n-1个数,同理第三轮只需要排前n-2个数,第i轮只需要排前n-1-i个数 --------------------编程问答-------------------- 楼主还是使用Linq,以前的一些方法已经不适用了没必要去在研究,使用Linq可以轻松解决排序的问题,代码简单。 --------------------编程问答--------------------
引用 1 楼 czarten 的回复:
n个数,第一轮排完后,最后一个数一定是最大的,所以第二轮只需要排前n-1个数,同理第三轮只需要排前n-2个数,第i轮只需要排前n-1-i个数


说错了,是n+1-i个数,因为程序中的轮数是从0开始计数 --------------------编程问答--------------------
引用 2 楼 Lemon360 的回复:
楼主还是使用Linq,以前的一些方法已经不适用了没必要去在研究,使用Linq可以轻松解决排序的问题,代码简单。


对算法的理解是每个程序员都应具备的,只会用一些所谓的强大功能,到头来吃亏的是自己。 --------------------编程问答--------------------
引用 2 楼 Lemon360 的回复:
楼主还是使用Linq,以前的一些方法已经不适用了没必要去在研究,使用Linq可以轻松解决排序的问题,代码简单。


不懂算法,数据结构这些基础知识,就相当于空练了招式,一击则败。 --------------------编程问答-------------------- 说了半天也不知道你想问什么。
当然要两个循环,第一个代表你需要这么多趟,第二个代表每一趟都要从数组的开始处到有序部分之前这么扫描一次,并且进行交换。 --------------------编程问答-------------------- 要温故而知新 --------------------编程问答-------------------- 第二个这样写可以减小空间复杂度,如果不考虑空间复杂度的话,可以和第一个循环一样的写法 --------------------编程问答-------------------- 这个冒泡程序是比较数组之间相邻元素的大小,将较大的元素放在后面。

i每增加1,就说明找到一个最大数。j每增加1,说明进行了一次相邻元素的比较。通过这样的嵌套循环,可将数组中最大的元素放进数组的最后位置,第二大的元素放进数组倒数第二的位置,将第三大的元素放进数组倒数第三的位置,以此类推,最小元素被放进了数组的第一位,进行就完成了排序。

之所以要j<length-1-i,是为了减少内部循环的次数(就是对相邻元素进行比较的次数),提高冒泡程序的完成工作的效率,如果写成j<length-1,也是可以的,只是增加了一些不必要的循环。因为之前对i的循环,已经把最大的数字放进了数组后部,那么数组的后部就不必判断  if (array[j] > array[j + 1])。 --------------------编程问答-------------------- 简单的说,你有10个数,length=10;
第一次排序后,最大的那个数找到了,你下一步,只要判断剩余9个数的顺序就行了

就是length=length-1;

冒泡一次,循环处理的数据就会少一个,所以再减去次数i。 --------------------编程问答-------------------- --------------------编程问答-------------------- package sort;

import java.util.Arrays;

public class Sort {

public static void main(String[] args) {
int[] ary = { 5, 8, 63, 8, 9, 1, 3, 2, 45, 12 };
int[] ary1 = selectSort(ary);
int[] ary2 = insertSort(ary);
int[] ary3 = bubbleSort(ary);

System.out.println(Arrays.toString(ary1));
System.out.println(Arrays.toString(ary2));
System.out.println(Arrays.toString(ary3));
}

// 一: 选择排序
// 原理:
// a 将数组中的每个元素,与第一个元素比较如果这个元素小于第一个元素, 就将这个 两个元素交换.
// b 每轮使用a的规则, 可以选择出一个最小元素放到第一个位置.
// c 经过n-1轮比较完成排序
// 简单说: 每轮选择最小的放到前面.

public static int[] selectSort(int[] ary) {
int count = 0;
for (int i = 0; i < ary.length - 1; i++) {
for (int j = i + 1; j < ary.length; j++) {
if (ary[i] > ary[j]) { // 将小的数往前移,第一轮将最小的移到到第一个位置,然后继续第二轮比较
int temp = ary[i];
ary[i] = ary[j];
ary[j] = temp;
}
count++;// 计算运算了多少次!
}
}
System.out.println(count);
return ary;

}

// 二: 插入排序
// 第一部分包含了这个数组的所有元素,但将最后一个元素除外,而第二部分就只包含这一个元素
// 在第一部分排序后,再把这个最后元素插入到此刻已是有序的第一部分里的位置

public static int[] insertSort(int[] ary) {
int count = 0;
for (int i = 1; i < ary.length; i++) {
int temp = ary[i];
int j;
for (j = i - 1; j >= 0; j--) {
if (temp < ary[j]) {
ary[j + 1] = ary[j];// 移动 ary[j]->ary[j+1];留出下标j的位置让temp插入
count++;
} else {
count++;
break;
}

}
ary[j + 1] = temp;// 插入 temp -> ary[j+1]是因为for循环中j--,所以跳出循环时j的值是j-1
// 就应该把temp的值赋给ary[j+1]
}
System.out.println(count); // 计算运算次数
return ary;

}

// 三: 冒泡排序
// 原理: a 逐一比较数组中相邻的两个元素, 如果后面
// 的数字小于前面的数字, 就交换先后元素.
// b 经过一个轮次的比较, 一定有一个最大的排
// 在最后的位置.
// c 每次比较剩下的元素, 经过n-1次比较, 可以
// 实现排序
// 简单说: 比较交换相邻元素,每次最大的漂移到最后

public static int[] bubbleSort(int[] ary) {
int count = 0;
for (int i = 0; i < ary.length - 1; i++) {
boolean tap = false;
for (int j = 0; j < ary.length - i - 1; j++) {
if (ary[j] > ary[j + 1]) {// 相邻两数进行比较,大的就移动到后面去!
int temp = ary[j];
ary[j] = ary[j + 1];
ary[j + 1] = temp;
tap = true;
}
count++;// 计算运算了多少次!
// System.out.println(Arrays.toString(ary));
}
if (!tap) {
break;// 如果j 与 j+1没有交换,跳出循环!
}
}
System.out.println(count);
return ary;

}
}
--------------------编程问答-------------------- 我记得谭浩强的c语言编程上有讲解的。
楼主你还是去看看书吧,这不是什么难题。书上描述的应该比这里说的要严谨,而且自己看明白了比别人给你讲明白了印像要深刻得多。 --------------------编程问答-------------------- 第一次“冒泡”,把最大的一个数顶到最后(最高)了,也就是位置 length - 1。

那么下一趟for循环,这次冒泡,就把剩下的数的最大的数顶到位置 length - 1 - 1。

再下一次,冒泡,把剩下的数的最大值顶到位置 length -1 -2 就行了

....................

事实上动用你的想象力,你会看到,即使写 for (int j = 0; j < length - 1; j++) 肯定也是得到同样的结果。但是实际上多做了一些判断,因为很明显 length -1 -i 位置以后的数字已经是最大的数了,也就是说这些后边位置上进行 if (array[j] > array[j + 1]) 判断永远不会成立的。 --------------------编程问答-------------------- 嗯,我看到 #9楼 #10楼已经说明了。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,