0
点赞
收藏
分享

微信扫一扫

BFPRT 算法


今天我写这个算法的时候发现了很多运行的时候总是有很多问题,先挂上代码:

package org.iaiai.suanfa;

/**
 * 
 * <p>
 * Title: BFPRT.java
 * </p>
 * <p>

 * </p>
 * <p>

 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-8-5
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
public class BFPRT {

	public static final int N = 5;
	public static int number[];

	public BFPRT(int size) {
		number = new int[size];
		System.out.println("the arrray is:");
		for (int i = 0; i < size; i++) {
			number[i] = (int) (Math.random() * 12);
			System.out.print(number[i] + ",");
		}
		System.out.println("");
	}

	public void sw(int i, int j) {
		int tmp = number[i];
		number[i] = number[j];
		number[j] = tmp;

		/*
		 * number[i]^=number[j]; number[j]^=number[i]; number[i]^=number[j];
		 */
	}

	public void bubleSort(int begin, int end) { // /元素不包括end的
		for (int i = end - 1; i > 0; i--) {
			for (int j = begin; j < i; j++) {
				if (number[j] > number[j + 1]) {
					sw(j, j + 1);
				}
			}
		}
	}

	public int partion(int begin, int end, int NUM) {// 将小于NUM的放在左边,将大于等于NUM的放在右边
		int pbegin = begin;
		int pend = end - 1;
		System.out.println("the NUM:" + NUM);
		while ((pbegin <= pend)) {
			System.out.println("pbegin=" + pbegin);
			System.out.println("number[pbegin]=" + number[pbegin]);
			System.out.println("number[pbegin]>=NUM: "
					+ (number[pbegin] >= NUM));
			if ((number[pbegin] >= NUM)) {
				while ((number[pend] >= NUM)) {
					System.out.println("pend=" + pend);

					pend--;
				}
				if (pbegin > pend) { // 这里要判断是否越界了
					return pbegin;
				}
				sw(pbegin, pend);
				System.out.println("pend==" + pend + " and pbegin=" + pbegin);
				pend--;
			}
			pbegin++;
		}
		return pbegin;
	}

	public void printARR(int begin, int end) {
		System.out.println("the array is:");
		for (int i = begin; i < end; i++) {
			System.out.print(number[i] + ",");
		}
		System.out.print("\n");
	}

	public int selectKnum(int begin, int end, int K) { // 寻找第K小的
		// printARR(begin,end);
		int i = 0;
		int size = end - begin;
		if (size <= 9) {
			if (K > size) {
				System.out
						.println("the K is:" + K + " and the size is:" + size);
				System.out.println("the K is overall the numbers length");
				return -1;
			}
			bubleSort(begin, end);
			return number[begin + K - 1];
		}
		for (i = 0; i < (end - begin) / N; i++) {
			bubleSort(i * N + begin, (i + 1) * N + begin);
			sw(begin + i, i * N + 2 + begin); // 将每一组中的中位数放到数组的前面去
		}
		printARR(begin, end);
		System.out.println("the i is:" + i);
		int x = selectKnum(begin, begin + i, (end - begin + 6) / 10);
		int Pnow = partion(begin, end, x);
		int j = Pnow - begin;
		printARR(begin, end);
		System.out.println("the x is:" + x);
		System.out.println("the pNow is:" + Pnow);
		System.out.println("the j is:" + j);
		System.out.println("the K is: " + K);
		if (K > j) {
			return selectKnum(Pnow, end, K - j);
		} else {
			return selectKnum(begin, Pnow, K);
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int size = 15;
		int nth = 14;
		BFPRT A = new BFPRT(size);
		int num = A.selectKnum(0, size, nth);
		System.out.println("the " + nth + "'num is:" + num);
	}

}



运行后直接爆栈!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


[quote]the array is:

2,3,2,7,8,2,2,2,3,9,8,

the x is:2

the pNow is:4

the j is:0

the K is: 10

the array is:

3,2,2,7,8,2,2,2,3,9,8,

the i is:2

the NUM:2

pbegin=4

number[pbegin]=2

number[pbegin]>=NUM: true

pend=14

pend=13

pend=12

pend=11

pend=10

pend=9

pend=8

pend=7

pend=6

pend=5

pend=4

the array is:

2,3,2,7,8,2,2,2,3,9,8,

the x is:2

the pNow is:4

the j is:0

the K is: 10

the array is:

3,2,2,7,8,2,2,2,3,9,8,

the i is:2

the NUM:2

pbegin=4

number[pbegin]=2

number[pbegin]>=NUM: true

pend=14

pend=13

pend=12

pend=11

pend=10

pend=9

pend=8

pend=7

pend=6

pend=5

pend=4

the array is:

2,3,2,7,8,2,2,2,3,9,8,

the x is:2

the pNow is:4

the j is:0

the K is: 10

the array is:

3,2,2,7,8,2,2,2,3,9,8,

the i is:2

the NUM:2

pbegin=4

number[pbegin]=2

number[pbegin]>=NUM: true

pend=14

pend=13

pend=12

pend=11

pend=10

pend=9

pend=8

pend=7

pend=6

pend=5

pend=4

the array is:

2,3,2,7,8,2,2,2,3,9,8,

the x is:2

the pNow is:4

the j is:0

the K is: 10

the array is:

3,2,2,7,8,2,2,2,3,9,8,

the i is:2

the NUM:2

pbegin=4

number[pbegin]=2

number[pbegin]>=NUM: true

pend=14

pend=13

pend=12

pend=11

pend=10

pend=9

pend=8

pend=7

pend=6

pend=5

pend=4

the array is:

2,3,2,7,8,2,2,2,3,9,8,

the x is:2

the pNow is:4

the j is:0

the K is: 10

Exception in thread "main" java.lang.StackOverflowError

 at sun.nio.cs.ext.GB18030$Encoder.encodeArrayLoop(Unknown Source)

 at sun.nio.cs.ext.GB18030$Encoder.encodeLoop(Unknown Source)

 at java.nio.charset.CharsetEncoder.encode(Unknown Source)

 at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)

 at sun.nio.cs.StreamEncoder.write(Unknown Source)

 at java.io.OutputStreamWriter.write(Unknown Source)

 at java.io.BufferedWriter.flushBuffer(Unknown Source)

 at java.io.PrintStream.write(Unknown Source)

 at java.io.PrintStream.print(Unknown Source)

 at java.io.PrintStream.println(Unknown Source)

 at BFPRT.printARR(BFPRT.java:59)

 at BFPRT.selectKnum(BFPRT.java:83)

 at BFPRT.selectKnum(BFPRT.java:94)

 at BFPRT.selectKnum(BFPRT.java:94)[/quote]


看到没有,总是在两个数组之间不停的切换,原因是在数字有相同的情况下,可能存在一种情况就是那样的,select与partion不停的切换,而且此时select找到的中位数在第一位,后来的partion找到把数组还原了。



所以我的程序是有BUG的,如何消除由相同数的影响,你可以采用重新随机打乱来操做(但是还是可能会出现那样的情况,比如全部是2),[color=darkred]所以这样地方法适用在所有数字互不相同的情况下面。切记这个话,所以这个算法不是万能的,要分情况使用;[/color]


举报

相关推荐

0 条评论