private int select(int[] data, int start, int end, int k) {
        if (start == end) {
            return data[k-1];
        }
        int t = data[start], i = start, j = end + 1;
        while (true) {
            do {
                i++;
            } while (i <= end && data[i] < t);
            do {
                j--;
            } while (data[j] > t);
            if (i > j) {
                break;
            }
            swap(data, i, j);
        }
        swap(data, start, j);
        if (j<k) {
            return select(data, j+1, end, k);
        } else if (j > k) {
            return select(data, start, j-1, k);
        } else {
            return data[k-1];
        }
    }