2008年4月22日星期二

算法——递归与分治之快速排序

快速排序的基本思想是,对于输入的子数组a[p:r],进行
(1)分解(Divide):以a[p]为基准元素将a[p:r]划分为三段a[p:q-1],a[q]和a[q+1:r].是a[p:q-1]中任何一个元素小于等于a[q],而a[q+1:r]中任何一个元素大于a[q].下表q在划分过程中确定.
(2)递归(Conquer):通过递归调用快速排序算法分别对a[p:q-1]和a[q+1,r]进行排序.
(3)合并(Merge):由于对a[p:q-1]和a[q+1:r]的排序是就地进行的,所以在a[p:q-1]和a[q+1:r]都已排好序后,不需要执行任何计算,a[p:r]就已排好序.

#include "iostream.h"

void QuickSort(int a[], int p, int r);
int Partition(int a[], int p, int r);
void print(int a[], int length);

int main(){
int a[] = {3, 5, 8, 2, 4, 7, 1};
print(a, 7);
QuickSort(a, 0, 6);

print(a, 7);

return 0;
}

void QuickSort(int a[], int p, int r)
{
if(p < r){
int q = Partition(a, p, r);
print(a, 7);
QuickSort(a, p, q-1);
print(a, 7);
QuickSort(a, q+1, r);
print(a, 7);
}
}

int Partition(int a[], int p, int r)
{
int i = p, j = r + 1;
int x = a[p];

while(true){
while(a[++i] < x && i < r);
while(a[--j] > x);
if(i >= j)
break;
//Swap(a[i], a[j]);
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
a[p] = a[j];
a[j] = x;

return j;
}

void print(int a[], int length)
{
for(int i = 0; i < length; i++){
cout << a[i] << ", ";
}
cout << endl;
}

算法——递归与分治之最接近点对问题

给定平面上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对的距离最小。
1.一维的情况

package com.yuxh.nearestPoints;


import java.util.Collections;
import java.util.LinkedList;
import java.lang.Math;
import com.yuxh.util.SimplePrint;


/**
* @author YuXH
* @version $Revision: 1.0 $, $Date: 2008/04/22 16:27:55 $
*/
public class NearestPoints {


/*
* 求一维点集s的最接近点对的算法
*/
public int cpair1(int s[]) {
int d = 1000;
if (s.length == 2) {
d = Math.abs(s[0] - s[1]);
} else if (s.length == 1) {
d = 1000;
} else {
// m = s中各点的中位数
// 构造s1和s2
int s1[] = new int[(s.length + 1) / 2];
int s2[] = new int[s.length / 2];
int midDivArray[] = midDiv(s);
for (int i = 0; i < midDivArray.length; i++) {
if (i < (midDivArray.length + 1) / 2) {// 构造s1
s1[i] = midDivArray[i];
} else {// 构造s2
s2[i - ((s.length + 1) / 2)] = midDivArray[i];
}
}


SimplePrint.print("s1: ", s1);
SimplePrint.print("s2: ", s2);


int d1 = cpair1(s1);
int d2 = cpair1(s2);
int p = max(s1);
int q = min(s2);
int res[] = { d1, d2, q - p };
d = min(res);
}


System.out.println("d: " + d);
return d;
}


/*
* 求s中的最大元素
*/
private int max(int s[]) {
LinkedList list = new LinkedList();
for (int i = 0; i < s.length; i++) {
list.add(s[i]);
}


return Collections.max(list);
}


/*
* 求s中的最小元素
*/
private int min(int s[]) {
LinkedList list = new LinkedList();
for (int i = 0; i < s.length; i++) {
list.add(s[i]);
}


return Collections.min(list);
}


/*
* 求中位数
*/
private int[] midDiv(int inputArray[]) {
int midLoc = inputArray.length / 2;
for (int i = 0; i < inputArray.length; i++) {
if (i < midLoc) {
if (inputArray[i] > inputArray[midLoc]) {
// 交换
int temp = inputArray[i];
inputArray[i] = inputArray[midLoc];
inputArray[midLoc] = temp;
}
} else {
if (inputArray[i] < inputArray[midLoc]) {
// 交换
int temp = inputArray[i];
inputArray[i] = inputArray[midLoc];
inputArray[midLoc] = temp;
}
}
}


return inputArray;
}


public static void main(String[] args) {
NearestPoints np = new NearestPoints();
int testArray[] = { 2, 10, 6, 79, 15, 68, 45, 66, 75 };
SimplePrint.print("origenal array: ", testArray);
System.out.println("End of d: " + np.cpair1(testArray));
}
}

2008年4月2日星期三

神奇,可以上wekipedia了!

今天无意,居然上了wikipedia!

听完微软亚洲研究院副院长王坚的讲座,提到以个叫memex的东西,觉得比较有意思,
回来Google了一下,"手气不错"。
奇迹出现了,居然转到wikipedia上了,因该有人知道wikipedia是被GFW长期封杀的对象,再从wikipedia的memex页面转到wikipedia的主页,成功了。不管是浏览内容还是搜索资料,速度都很快。
wikipedia就不用介绍了吧
看看主页:


看看wikipedia上的GFW:

好,现在分享一下wikipedia
http://en.wikipedia.org/wiki/Main_Page

只是不明白,为什么中国大陆要封了wikipedia这么好的资源,实在可惜