大神们,谁会双向冒泡排序算法就进来帮帮小弟。。。。。。

I_am_a_Beginner 2015-06-04 02:41:19
以下是一个双向冒泡排序算法

int high = table.length;
int left = 1;
int right = high - 1;
int t = 0;
do {
//正向部分
for (int i = right; i >= left; i--)
{
if (table[i] < table[i - 1])
{
int temp = table[i];
table[i] = table[i - 1];
table[i - 1] = temp;
t = i;
}
}
left = t + 1;
//反向部分
for (int i = left; i < right + 1; i++)
{
if (table[i] < table[i - 1])
{
int temp = table[i];
table[i] = table[i - 1];
table[i - 1] = temp;
t = i;
}
}
right = t - 1;
} while (left <= right);


问题;
1.这个双向冒泡排序算法是这么去理解的?可以的话举一些例子给我看看!
2.它是什么时候进行交换的?
...全文
565 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这个的关键是看t 正向部分是从右向左遍历,找最小的 当if (table[i] < table[i - 1])成立的时候,说明当前比较的2个值,左面的大,右面的小,要交换,这个时候我们只知道左面的比右面的大,并不知道其与之前的值的大小关系,所以在这里记录一下下标值到t,如果继续从右向左比较,if (table[i] < table[i - 1]) 不成立,意味着左面的值都要比右面的小,符合我们找最小的要求,这个时候所记录的t就是一个左边界。 反之,左向右遍历,找最大的 当if语句成立时,说明当前比较的2个值,左面的大,需要交换,并记录当前下标值到t。继续从左向右遍历,如果if语句不成立,意味着右面的都大,符合我们找右面大的要求,这个时候t就是个右边界。
傻傻de点点 2015-06-10
  • 打赏
  • 举报
回复
public class DoubleBubbleSort {
	public static void main(String[] args) {
		int[] a = {6, 8, 9, 3, 4, 7, 5, 2, 0, 1};
		// 排序前
		for (int i : a) {
			System.out.print(i + " ");
		}
		System.out.println();
		Sort(a);
		// 排序后
		for (int i : a) {
			System.out.print(i + " ");
		}
	}

	public static int[] Sort(int[] table) {
        int high = table.length;
        int left = 1;
        int right = high - 1;
        int t = 0;
        do {
            // 从右向左
            for (int i = right; i >= left; i--) 
            {
                if (table[i] < table[i - 1]) 
                {
                    int temp = table[i];
                    table[i] = table[i - 1];
                    table[i - 1] = temp;
                    t = i;
                }
            }
            
            left = t + 1;
            // 从左向右
            for (int i = left; i < right + 1; i++) 
            {
                if (table[i] < table[i - 1]) 
                {
                    int temp = table[i];
                    table[i] = table[i - 1];
                    table[i - 1] = temp;
                    t = i;
                }
            }
            right = t - 1;
        } while (left <= right);
		return table;
	}
	
}
I_am_a_Beginner 2015-06-10
  • 打赏
  • 举报
回复
引用 13 楼 jc890904 的回复:
从左往右的循环,t的左边是有序区域,怎么可能从t - 1开始。注意看你发的代码的17~19行,17行把left赋值为t + 1, 19行循环从left开始。我不知道第6行和第18行的注释是谁写的,完全写错,而且这样的位置很容易造成误解。 最简单的办法,写个测试类,把排序算法每行都设置断点,逐行调试,监视每次循环数组每个元素的变化,那样更容易理解。
那你可不可以以我的例子写一个测试类,让我有更好的理解???
傻傻de点点 2015-06-09
  • 打赏
  • 举报
回复
引用 12 楼 I_am_a_Beginner 的回复:
[quote=引用 10 楼 jc890904 的回复:] 以从左往右的循环为例,每次循环从left开始,到t的位置做元素交换,这就意味着从left到t的区域有序,既然有序排序就可直接跳过,下次循环从t+1开始即可。从右往左一样理解就行了。
应该下一次循环从t-1吧???[/quote] 从左往右的循环,t的左边是有序区域,怎么可能从t - 1开始。注意看你发的代码的17~19行,17行把left赋值为t + 1, 19行循环从left开始。我不知道第6行和第18行的注释是谁写的,完全写错,而且这样的位置很容易造成误解。 最简单的办法,写个测试类,把排序算法每行都设置断点,逐行调试,监视每次循环数组每个元素的变化,那样更容易理解。
Bruce's Hand 2015-06-08
  • 打赏
  • 举报
回复
冒泡排序每次循环就是把最小或最大的值放到数组的最左或最右。 //正向部分 for (int i = right; i >= left; i--) { if (table[i] < table[i - 1]) { int temp = table[i]; table[i] = table[i - 1]; table[i - 1] = temp; t = i; } } left = t + 1; 这个是从后向前,怎么是正向呢?这点不是很明白。 具体执行应该是,从后向前去比较,如果后一个(第i个)小于前一个(第i-1个),则交换。并保存当前发生交换的下标,就是t值。保存t值的目的是:确定下一次循环的开始位置和结束位置。因为如果前面的程序已经有序 了,t值就不会发生变化。 //反向和正向就是一样的了。不过是找当前最大的元素而已。
傻傻de点点 2015-06-08
  • 打赏
  • 举报
回复
引用 8 楼 I_am_a_Beginner 的回复:
[quote=引用 1 楼 jc890904 的回复:] 在每一次排序动作,先从左往右进行一次冒泡排序,再从右往左进行一次冒泡排序
你这样讲是不对的,应该是第一个for是从右到左找到当中的最小值;而第二个for是从左到右找到当中的最大值。 新问题来了!!! 在if里面的t是不是代表数较小或数较大交换前所对应的下标值了?? 而代码中left = t + 1和right = t - 1分别代表什么意义了??最好举个例子说明情况!!![/quote] 1. 是的。 2. 数组0到left位置,为有序区域;right到数组末尾,也是有序区域。以从左往右的循环为例,每次循环从left开始,到t的位置做元素交换,这就意味着从left到t的区域有序,既然有序排序就可直接跳过,下次循环从t+1开始即可。从右往左一样理解就行了。
I_am_a_Beginner 2015-06-08
  • 打赏
  • 举报
回复
引用 10 楼 jc890904 的回复:
以从左往右的循环为例,每次循环从left开始,到t的位置做元素交换,这就意味着从left到t的区域有序,既然有序排序就可直接跳过,下次循环从t+1开始即可。从右往左一样理解就行了。
应该下一次循环从t-1吧???
I_am_a_Beginner 2015-06-07
  • 打赏
  • 举报
回复
wenjinruo 2015-06-06
  • 打赏
  • 举报
回复
可以看看两个子循环在做什么,假设序列是未排序的,未排序地一个元素下标为left(初始化为0),最后一个元素下标为rught(初始化为length-1) 1.每次循环,第一个子循环把最小的放到最前面, 是在未排序的序列中操作,每排好一个,left加一 2.理解了第一个子循环,第二个子循环因该就理解了!把未排序的最大元素放置到最后,right减一 3.当left>=right说明两边都已排好序
I_am_a_Beginner 2015-06-06
  • 打赏
  • 举报
回复
引用 1 楼 jc890904 的回复:
在每一次排序动作,先从左往右进行一次冒泡排序,再从右往左进行一次冒泡排序
你这样讲是不对的,应该是第一个for是从右到左找到当中的最小值;而第二个for是从左到右找到当中的最大值。 新问题来了!!! 在if里面的t是不是代表数较小或数较大交换前所对应的下标值了?? 而代码中left = t + 1和right = t - 1分别代表什么意义了??最好举个例子说明情况!!!
Old-Summer 2015-06-06
  • 打赏
  • 举报
回复

<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title></title>
<%@ include file="meta.jsp"%>
<%@ include file="css.jsp"%>
<style>
.container {
	width:100px;
	height:100%;
	margin-top:100px;
}
</style>
</head>
<body>
asdfasfas
</body>
</html>
靳以山 2015-06-05
  • 打赏
  • 举报
回复
debug一下,每循环一次,把数组输出来看看,多试几次就明白了
  • 打赏
  • 举报
回复
package array;

/*
 * 冒泡排序,是个嵌套循环,每次按照特定的要求比较数组中相邻的两个元素,满足要求就交换元素,一次遍历能够确定一个元素
 * 双向冒泡,是一个循环内嵌套两个循环,循环一找最小,循环二找最大
 * 
 */

public class T {
    public static void main(String[] args) {
        int[] table = new int[10];
    	
    	for(int i = 0;i < table.length;i++){
    		int x = (int)(Math.random()*200);
    		table[i] = x;
    	}
    	System.out.print("[");
    	for(int i = 0;i < table.length;i++){
    		System.out.print(table[i] + "\t");
    	}
    	System.out.print("]");
    	System.out.println();
    	System.out.println("=============");
    	
        int left = 0;//左边界下标
        int right = table.length - 1;//右边界下标
        
        while (table.length > 1 &&  right - left >= 1){//当数组里的元素多余1个  ,且边界内至少有2个元素时循环      	
        	//正向部分,内循环一,遍历一次找到最小的元素,
            for (int i = right; i > left; i--) //应为每次要比较2个元素,比较到倒数第二个元素后就不用比较了
            {                                   //每次循环的次数是当前比较元素的总数 -1
                if (table[i] < table[i - 1]) 
                {
                    int temp = table[i];
                    table[i] = table[i - 1];
                    table[i - 1] = temp;
                }
            }
            System.out.print("[");
        	for(int i = 0;i < table.length;i++){
        		System.out.print(table[i] + "\t");
        	}
        	System.out.print("]");
        	System.out.println();
        	//table[left]为最小
            left++;//左边界右移1位
            //反向部分,内循环二,遍历一次找到最大的元素
            if(table.length > 2 && left != right){//如果数组只有2个元素,或者当次外循环right-left=1时,循环二不必运行
                for (int i = left; i < right ; i++) 
                {
                    if (table[i] > table[i + 1]) 
                    {
                        int temp = table[i];
                        table[i] = table[i + 1];
                        table[i + 1] = temp;
                    }
                }
                System.out.print("[");
            	for(int i = 0;i < table.length;i++){
            		System.out.print(table[i] + "\t");
            	}
            	System.out.print("]");
            	System.out.println();
            	//table[right]为最大
                right--;//右边界左移1位
            }
        
        
	}
}
}
  • 打赏
  • 举报
回复
这段代码是不是有点问题? package array; /* * 冒泡排序,是个嵌套循环,每次按照特定的要求比较数组中相邻的两个元素,满足要求就交换元素,一次遍历能够确定一个元素 * 双向冒泡,是一个循环内嵌套两个循环,循环一找最小,循环二找最大 * */ public class T { public static void main(String[] args) { int[] table = new int[10]; for(int i = 0;i < table.length;i++){ int x = (int)(Math.random()*200); table[i] = x; } System.out.print("["); for(int i = 0;i < table.length;i++){ System.out.print(table[i] + "\t"); } System.out.print("]"); System.out.println(); System.out.println("============="); int left = 0;//左边界下标 int right = table.length - 1;//右边界下标 while (table.length > 1 && right - left >= 1){//当数组里的元素多余1个 ,且边界内至少有2个元素时循环 //正向部分,内循环一,遍历一次找到最小的元素, for (int i = right; i > left; i--) //应为每次要比较2个元素,比较到倒数第二个元素后就不用比较了 { //每次循环的次数是当前比较元素的总数 -1 if (table[i] < table[i - 1]) { int temp = table[i]; table[i] = table[i - 1]; table[i - 1] = temp; } } System.out.print("["); for(int i = 0;i < table.length;i++){ System.out.print(table[i] + "\t"); } System.out.print("]"); System.out.println(); //table[left]为最小 left++;//左边界右移1位 //反向部分,内循环二,遍历一次找到最大的元素 if(table.length > 2 && left != right){//如果数组只有2个元素,或者当次外循环right-left=1时,循环二不必运行 for (int i = left; i < right ; i++) { if (table[i] > table[i + 1]) { int temp = table[i]; table[i] = table[i + 1]; table[i + 1] = temp; } } System.out.print("["); for(int i = 0;i < table.length;i++){ System.out.print(table[i] + "\t"); } System.out.print("]"); System.out.println(); //table[right]为最大 right--;//右边界左移1位 } } } }
javacankillyou 2015-06-04
  • 打赏
  • 举报
回复
个人见解,不保证正确,不爽可以来打我。。。 我觉得理解这段代码的关键在于理解 t 在做什么事。正向排序那里,t 记录的是 左边 有序 数组 的最后一个数。比如数组 1 2 3 4 5 76 22 12 44 66 23 。t 记录的就是 5 的下标。所以正向排序一遍下来,左边有一小段数组已经有序。而反向排序的 t 呢,记录的是右边有序数组的第一个数。比如上面的数组反向排序之后1 2 3 4 5 7 22 12 44 66 23 76 。t 记录的就是23 的下标。这时可以看到,1 2 3 4 5 ,和23 76 都是有序的吧。这时对中间的 数组再进行while 循环,当left 等于right的时候,就全都有序了。。 我也理解的一般般。希望高手用更简洁有力的见解让我眼前一亮。顺便问一句,这里有人互粉吗?一起学习行吗?我的粉丝才一人,还是僵尸粉。他好久没上了。。。。
傻傻de点点 2015-06-04
  • 打赏
  • 举报
回复
在每一次排序动作,先从左往右进行一次冒泡排序,再从右往左进行一次冒泡排序,用left和right分别记录左右两边已排序的元素位置,left大于right时,排序结束。例如: 8 2 6 9 7 3 4 5 1 0 第一次 [0] 8 2 6 7 3 4 5 1 [9] 第二次 [0 1] 2 6 7 3 4 5 [8 9] 第三次 [0 1 2] 6 3 4 5 [7 8 9] 第四次 [0 1 2 3] 4 5 [6 7 8 9] 第五次 [0 1 2 3 4] [5 6 7 8 9] 第六次 此时left = 5,right = 4,left > right,排序结束。 交换元素跟普通冒泡排序一毛一样,没有任何区别。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧