Segment tree java implementation [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Do you know a good implementation of a (binary) segment tree in Java?

public class SegmentTree {
public static class STNode {
int leftIndex;
int rightIndex;
int sum;
STNode leftNode;
STNode rightNode;
}
static STNode constructSegmentTree(int[] A, int l, int r) {
if (l == r) {
STNode node = new STNode();
node.leftIndex = l;
node.rightIndex = r;
node.sum = A[l];
return node;
}
int mid = (l + r) / 2;
STNode leftNode = constructSegmentTree(A, l, mid);
STNode rightNode = constructSegmentTree(A, mid+1, r);
STNode root = new STNode();
root.leftIndex = leftNode.leftIndex;
root.rightIndex = rightNode.rightIndex;
root.sum = leftNode.sum + rightNode.sum;
root.leftNode = leftNode;
root.rightNode = rightNode;
return root;
}
static int getSum(STNode root, int l, int r) {
if (root.leftIndex >= l && root.rightIndex <= r) {
return root.sum;
}
if (root.rightIndex < l || root.leftIndex > r) {
return 0;
}
return getSum(root.leftNode, l, r) + getSum(root.rightNode, l, r);
}
/**
*
* #param root
* #param index index of number to be updated in original array
* #param newValue
* #return difference between new and old values
*/
static int updateValueAtIndex(STNode root, int index, int newValue) {
int diff = 0;
if(root.leftIndex==root.rightIndex && index == root.leftIndex) {
// We actually reached to the leaf node to be updated
diff = newValue-root.sum;
root.sum=newValue;
return diff;
}
int mid = (root.leftIndex + root.rightIndex) / 2;
if (index <= mid) {
diff= updateValueAtIndex(root.leftNode, index, newValue);
} else {
diff= updateValueAtIndex(root.rightNode, index, newValue);
}
root.sum+=diff;
return diff;
}
}

This has been implemented within the open source Layout Management SW Package project
Here is a link to the sub package
You might find the code useful. I have neither verified it nor run it and I cannot find the license the code is provided under from a quick search of the code and website so Caveat Emptor.
You may be able to contact the authors but the last activity appears to have been August 2008.

Here it is:
import java.util.Scanner;
public class MinimumSegmentTree {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
final int n = in.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = in.nextInt();
}
int sizeOfSegmentTree = (int) Math.pow(2, Math.ceil(Math.log10(n) / Math.log10(2)));
sizeOfSegmentTree = 2*sizeOfSegmentTree-1;
// System.out.println(sizeOfSegmentTree);
int[] segmentTree = new int[sizeOfSegmentTree];
formSegmentTree(a, segmentTree, 0, n-1, 0);
// for(int i=0; i<sizeOfSegmentTree; i++){
// System.out.print(segmentTree[i]+" ");
// }
// System.out.println();
final int q = in.nextInt();
for (int i = 0; i < q; i++) {
int s, e;
s = in.nextInt();
e = in.nextInt();
int minOverRange = getMinimumOverRange(segmentTree, s, e, 0, n-1, 0);
System.out.println(minOverRange);
}
}
private static int getMinimumOverRange(int[] segmentTree, int qs, int qe, int s, int e, int pos) {
if (qs <= s && qe >= e) {
return segmentTree[pos];
}
if (qs > e || s > qe) {
return 10000000;
}
int mid = (s + e) / 2;
return Math.min(getMinimumOverRange(segmentTree, qs, qe, s, mid, 2 * pos + 1),
getMinimumOverRange(segmentTree, qs, qe, mid+1, e, 2 * pos + 2));
}
private static void formSegmentTree(int[] a, int[] segmentTree, int s, int e, int pos) {
if (e - s == 0) {
segmentTree[pos] = a[s];
return;
}
int mid = (s + e) / 2;
formSegmentTree(a, segmentTree, s, mid, 2 * pos + 1);
formSegmentTree(a, segmentTree, mid+1, e, 2 * pos + 2);
segmentTree[pos] = Math.min(segmentTree[2 * pos + 1], segmentTree[2 * pos + 2]);
}
}

Algo and unit tests:
public class NumArrayTest {
#Test
public void testUpdateSumRange_WithEmpty() throws Exception {
NumArray numArray = new NumArray(new int[]{});
assertEquals(0, numArray.sumRange(0, 0));
}
#Test
public void testUpdateSumRange_WithSingleton() throws Exception {
NumArray numArray = new NumArray(new int[]{1});
assertEquals(1, numArray.sumRange(0, 0));
numArray.update(0, 2);
assertEquals(2, numArray.sumRange(0, 0));
}
#Test
public void testUpdateSumRange_WithPairElements() throws Exception {
NumArray numArray = new NumArray(new int[]{1,2,3,4,5,6});
assertEquals(12, numArray.sumRange(2, 4));
numArray.update(3, 2);
assertEquals(10, numArray.sumRange(2, 4));
}
#Test
public void testUpdateSumRange_WithInPairElements() throws Exception {
NumArray numArray = new NumArray(new int[]{1,2,3,4,5,6,7});
assertEquals(12, numArray.sumRange(2, 4));
numArray.update(3, 2);
assertEquals(10, numArray.sumRange(2, 4));
}
}
public class NumArray {
private final Node root;
private static class Node {
private final int begin;
private final int end;
private final Node left;
private final Node right;
private int sum;
public Node(int begin, int end, int sum, Node left, Node right) {
this.begin = begin;
this.end = end;
this.sum = sum;
this.left = left;
this.right = right;
}
public boolean isSingle() {
return begin == end;
}
public boolean contains(int i) {
return i >= begin && i <= end;
}
public boolean inside(int i, int j) {
return i <= begin && j >= end;
}
public boolean outside(int i, int j) {
return i > end || j < begin;
}
public void setSum(int sum) {
this.sum = sum;
}
}
public NumArray(int[] nums) {
if (nums.length == 0) {
root = null;
} else {
root = buildNode(nums, 0, nums.length - 1);
}
}
private Node buildNode(int[] nums, int begin, int end) {
if (begin == end) {
return new Node(begin, end, nums[begin], null, null);
} else {
int mid = (begin + end) / 2 + 1;
Node left = buildNode(nums, begin, mid - 1);
Node right = buildNode(nums, mid, end);
return new Node(begin, end, left.sum + right.sum, left, right);
}
}
public void update(int i, int val) {
if (root == null) {
return;
}
if (!root.contains(i)) {
throw new IllegalArgumentException("i not in range");
}
update(root, i, val);
}
private int update(Node node, int i, int val) {
if (node.isSingle()) {
node.setSum(val);
} else {
Node nodeToUpdate = node.left.contains(i) ? node.left : node.right;
int withoutNode = node.sum - nodeToUpdate.sum;
node.setSum(withoutNode + update(nodeToUpdate, i, val));
}
return node.sum;
}
public int sumRange(int i, int j) {
if (root == null) {
return 0;
}
return sumRange(root, i, j);
}
private int sumRange(Node node, int i, int j) {
if (node.outside(i, j)) {
return 0;
} else if (node.inside(i, j)) {
return node.sum;
} else {
return sumRange(node.left, i, j) + sumRange(node.right, i, j);
}
}
}

Related

How can I show the value of array with the Binary Search Tree of Comparison?

I going to do searching the value in the array, did I need to create a method to handle it? For example, the array logged 32,21,13,44,22, and I going to find 22 of the comparison. How can I implement this?
public class binarySearch {
public static void main(String [] args) {
int i = binarySearch(0, new int[]{32,21,13,44,22});
System.out.println("Iterations: " + i);
}
public static int binarySearch(int key, int[] array) {
int left = 0;
int mid;
int right = array.length - 1;
int i = 0;
while (left <= right) {
mid = (left + right) / 2;
int comp = Integer.compare(key, array[mid]);
i++;
if (comp < 0) {
right = mid - 1;
} else if (comp > 0) {
left = mid + 1;
} else {
break; // success
}
}
return i;
}
}
My final answer is here. May help you all in the future.
public static int binarySearch(int key, int[] array) {
int left = 0;
int mid;
int right = array.length - 1;
int i = 0;
while (left <= right) {
mid = (left + right) / 2;
int comp = Integer.compare(key, array[mid]);
i++;
if (comp < 0) {
right = mid - 1;
} else if (comp > 0) {
left = mid + 1;
} else {
break; // success
}
}
return i;
}
If you have shuffled array, all you can do is go through an array and find your number.
BinarySearch works only with sorted array. I think your solution could look like this:
public static int binarySearch(int[] arr, int key) {
Arrays.sort(arr);
return Arrays.binarySearch(arr, key);
}

I'am confused that the random quick sort is slower than normal quick sort

With the Introduction to algorithm .The Professor intro that the random quick sort can decrease the percentage of bad situation and improve the performance of time cost.But I wonder if there any problem with my code that cause the result
in contrast.
Here are my java code
public class quickSort {
public final int size = 200000;
public final int times = 10;
#Test
public void quick_sort() {
int test1[] = new int[size];
int test2[];
int k = 0;
long t1 = 0;
long t2 = 0;
for (int i = 0; i < size; i++) {
test1[i] = i;
}
test2 = test1.clone();
while (k < times) {
shuffle(test1);
shuffle(test2);
long start1 = System.currentTimeMillis();
split1(test1, 0, test1.length -1);
t1 += System.currentTimeMillis() - start1;
long start2 = System.currentTimeMillis();
split2(test2, 0, test2.length -1);
t2 += System.currentTimeMillis() - start2;
k++;
}
System.out.println("normal quick sort time is" + t1 + "ms");
System.out.println("random quick sort time is " + t2 + "ms");
}
public void split1(int[] arr, int start, int end) {
if (start >= end) {
return;
} else {
int middle = sort(arr, start, end);
split1(arr, start, middle - 1);
split1(arr, middle + 1, end);
}
}
public void split2(int[] arr, int start, int end) {
if (start >= end) {
return;
} else {
int middle = random_sort(arr, start, end);
split2(arr, start, middle - 1);
split2(arr, middle + 1, end);
}
}
// random quick sort
public int random_sort(int[] arr, int start, int end) {
int random = start + new Random().nextInt(end - start + 1);
int key = arr[random];
int loop = start;
int front = random == start ? start + 1 : start;
while (loop <= end) {
if (loop == random) {
loop++;
continue;
}
if (arr[loop] < key) {
int temp = arr[loop];
arr[loop] = arr[front];
arr[front] = temp;
front = front + 1 == random ? front += 2 : front + 1;
}
loop++;
}
if (front < end) {
int temp = arr[random];
arr[random] = arr[front];
arr[front] = temp;
} else {
front = end;
}
return front;
}
// normal quick sort
public int sort(int[] arr, int start, int end) {
int loop = start;
int key = arr[start];
int front = start + 1;
while (loop <= end) {
if (key > arr[loop]) {
int temp = arr[loop];
arr[loop] = arr[front];
arr[front++] = temp;
}
loop++;
}
if (front != 1) {
int temp = arr[front - 1];
arr[front - 1] = arr[start];
arr[start] = temp;
}
return front - 1;
}
// shuffle the Array
public void shuffle(int[] arr) {
int length = arr.length;
int random_num = 0;
for (int i = 0; i < length; i++) {
random_num = new Random().nextInt(length);
int temp = arr[i];
arr[i] = arr[random_num];
arr[random_num] = temp;
}
}
}

TimeLimitExceeded in finding maximum sum of a subarray

This is my solution for finding out the maximum sum of a subarray for a given array using Segment Tree (http://www.spoj.com/problems/GSS1/) but I am getting TLE (Time Limit Exceeded error) for this. Can anyone suggest more optimizations for this code?
public class segmentTree {
int st[];
segmentTree(int arr[], int n){
int x = (int)Math.ceil(Math.log(n)/Math.log(2));
int maxSize = (int)Math.pow(2, x)<<1 - 1;
st = new int[maxSize];
constructSTUtil(arr, 0, n-1, 0);
}
int getMid(int s, int e) {
return s + (e - s)>>1;
}
int getSumUtil(int ss, int se, int qs, int qe, int si)
{
if (qs <= ss && qe >= se)
return st[si];
if (se < qs || ss > qe)
return 0;
int mid = getMid(ss, se);
return getSumUtil(ss, mid, qs, qe, si<<1 + 1) +
getSumUtil(mid + 1, se, qs, qe, si<<1 + 2);
}
int getSum(int n, int qs, int qe)
{
if (qs < 0 || qe > n - 1 || qs > qe) {
return -1;
}
return getSumUtil(0, n - 1, qs, qe, 0);
}
int constructSTUtil(int arr[], int ss, int se, int si)
{
if (ss == se) {
st[si] = arr[ss];
return arr[ss];
}
int mid = getMid(ss, se);
st[si] = constructSTUtil(arr, ss, mid, si<<1 + 1) +
constructSTUtil(arr, mid + 1, se, si<<1 + 2);
return st[si];
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine().trim());
int array[] = new int[n];
String arr[] = new String[n];
arr = in.readLine().split(" ");
for(int i=0; i<n; i++){
array[i] = Integer.parseInt(arr[i].trim());
}
segmentTree tree = new segmentTree(array, n);
int m = Integer.parseInt(in.readLine());
while(m-- > 0){
String ind[] = new String[2];
ind = in.readLine().split(" ");
int x = Integer.parseInt(ind[0].trim());
int y =Integer.parseInt(ind[1].trim());
int maxSum = -999999999;
for(int i=x-1; i<=y-1; i++){
for(int j=x-1; j<=y-1; j++){
if(tree.getSum(n, i, j) > maxSum)
maxSum = tree.getSum(n, i, j);
}
}
System.out.println(maxSum);
}
}
}

QuickSort for big cases leads to stackoverflow

I am working on a school project that has to have 3 quicksorts with 1 pointer, 3 quicksorts with 2 pointers and 2 heaps.
I wrote the Quicksorts and one of the heaps so far.
The problem I have is quicksort works fine in small cases however in larger cases I get a stackoverflow.
Nore: each quicksort has an easy case in which it should run insertion sort.
Why do i get stack a overflow?
package prog3;
import java.util.Random;
public class ArraySorts {
public static void QuickSort1(int[] a, int n) {
QuickSort1(a, 0, n - 1);
}
private static void QuickSort1(int[] a, int start, int end) {
if ((end - start+1) <= 20) {
int num = (end + 1) - start;
insertion(a, num);
}
else {
// use first element as division between small and big
Random rand = new Random();
int pivotIndex = start + rand.nextInt(end - start);
swap(a, pivotIndex, start);
int pivot = a[start];
int partitionBook = partitionBook(a, start, end, pivot);
// recursively sort the smalls and then the bigs
QuickSort1(a, start, partitionBook - 1);
QuickSort1(a, partitionBook + 1, end);
}
}
public static void QuickSort2(int[] a, int n) {
// 2 ptr partition, random pivot, easiest case = 20
int left = 0;
int right = n - 1;
QuickSort2(a, left, right);
}
public static void QuickSort2(int[] a, int left, int right) {
if ((right - left + 1) <= 20) {
int num = right - left + 1;
insertion(a, num);
} else {
// int pivot = a[right];
Random rand = new Random();
int pivotIndex = left + rand.nextInt(right - left + 1);
swap(a, pivotIndex, right);
int pivot = a[right];
int partition = partition(a, left, right, pivot);
QuickSort2(a, 0, partition - 1);
QuickSort2(a, partition + 1, right);
}
}
public static void QuickSort3(int[] a, int n) {
QuickSort3(a, 0, n - 1);
}
private static void QuickSort3(int[] a, int start, int end) {
if ((end - start) <= 20) {
int num = (end + 1) - start;
insertion(a, num);
}
else {
// use first element as division between small and big
int pivot = a[start];
int partitionBook = partitionBook(a, start, end, pivot);
// recursively sort the smalls and then the bigs
QuickSort3(a, start, partitionBook - 1);
QuickSort3(a, partitionBook + 1, end);
}
}
public static void QuickSort4(int[] a, int n) {
// 2 ptr partition, random pivot, easiest case = 1
int left = 0;
int right = n - 1;
QuickSort4(a, left, right);
}
public static void QuickSort4(int[] a, int left, int right) {
if ((right - left + 1) <= 1) {
return;
}
// int pivot = a[right];
Random rand = new Random();
int pivotIndex = left + rand.nextInt(right - left + 1);
swap(a, pivotIndex, right);
int pivot = a[right];
// System.out.println("Pivot: " + pivot);
int partition = partition(a, left, right, pivot);
QuickSort4(a, 0, partition - 1);
QuickSort4(a, partition + 1, right);
}
public static void QuickSort5(int[] a, int n) {
// 2 ptr partition, random pivot, easiest case = 500
int left = 0;
int right = n - 1;
QuickSort5(a, left, right);
}
public static void QuickSort5(int[] a, int left, int right) {
if ((right - left + 1) <= 500) {
int num = right - left + 1;
insertion(a, num);
} else {
// int pivot = a[right];
Random rand = new Random();
int pivotIndex = left + rand.nextInt(right - left + 1);
swap(a, pivotIndex, right);
int pivot = a[right];
int partition = partition(a, left, right, pivot);
QuickSort5(a, 0, partition - 1);
QuickSort5(a, partition + 1, right);
}
}
public static void QuickSort6(int[] a, int n) {
QuickSort6(a, 0, n - 1);
}
private static void QuickSort6(int[] a, int start, int end) {
if ((end - start+1) <= 1) {
return;
}
else {
// use first element as division between small and big
Random rand = new Random();
int pivotIndex = start + rand.nextInt(end - start);
swap(a, pivotIndex, start);
int pivot = a[start];
int partitionBook = partitionBook(a, start, end, pivot);
// recursively sort the smalls and then the bigs
QuickSort1(a, start, partitionBook - 1);
QuickSort1(a, partitionBook + 1, end);
}
}
private static int partition(int[] a, int left, int right, int pivot) {
int leftCursor = left - 1;
int rightCursor = right;
while (leftCursor < rightCursor) {
while (a[++leftCursor] < pivot)
;
while (rightCursor > 0 && a[--rightCursor] > pivot)
;
if (leftCursor > rightCursor) {
break;
} else {
swap(a, leftCursor, rightCursor);
}
}
swap(a, leftCursor, right);
return leftCursor;
}
private static int partitionBook(int[] a, int start, int end, int pivot) {
// the index of the last small element
int lastSmall = start;
for (int unknown = start + 1; unknown <= end; unknown++) {
// see if the current element is small
if (a[unknown] < pivot) {
// and if so, put it with the other smalls
lastSmall++;
int temp = a[lastSmall];
a[lastSmall] = a[unknown];
a[unknown] = temp;
}
}
// put the pivot between the smalls and the bigs
int temp = a[start];
a[start] = a[lastSmall];
a[lastSmall] = temp;
return lastSmall;
}
public static void swap(int[] a, int left, int right) {
int temp = a[left];
a[left] = a[right];
a[right] = temp;
}
public static void printArray(int[] a) {
for (int i : a) {
System.out.print(i + " ");
}
}
public static int[] getArray() {
int size = 10;
int[] array = new int[size];
int item = 0;
for (int i = 0; i < size; i++) {
item = (int) (Math.random() * 100);
array[i] = item;
}
return array;
}
/**
* Will return the left child's index
*
* #param iIndex
* The index of the current position (Parent)
* #return The index of the left child
*/
static int Left(int iIndex) {
return ((iIndex << 1) + 1);
}
/**
* Will return the right child's index
*
* #param iIndex
* The index of the current position (Parent)
* #return The index of the right child
*/
static int Right(int iIndex) {
return ((iIndex << 1) + 2);
}
/**
* Will return the parent of the current index
*
* #param iIndex
* The index of the current position (Child)
* #return The index of the parent
*/
int Parent(int iIndex) {
return ((iIndex - 1) >> 1);
}
/**
* Swaps the values of the two index locations
*
* #param firstIndex
* the index of the first number to exchange.
* #param secondIndex
* The index of the second number to exchange.
* #param ipHeap
*/
static void Swap(int firstIndex, int secondIndex, int[] ipHeap) {
int iTemp = ipHeap[firstIndex];
ipHeap[firstIndex] = ipHeap[secondIndex];
ipHeap[secondIndex] = iTemp;
}
/**
* Determines if there needs to have a swap of a child and parent. It will
* determine which child needs to be swapped.
*
* #param parent
* index of the parent (current index)
* #param ipHeap
* The array that needs the operations performed.
* #param iSize
* The adjusted size of the array
* #return The index of the largest value.
*/
static int SwapWithChild(int parent, int[] ipHeap, int iSize) {
int leftChild = Left(parent);
int rightChild = Right(parent);
int iLargest = parent;
if (rightChild < iSize) {
if (ipHeap[leftChild] < ipHeap[rightChild]) {
iLargest = rightChild;
} else {
iLargest = leftChild;
}
if (ipHeap[parent] > ipHeap[iLargest]) {
iLargest = parent;
}
} else if (leftChild < iSize) {
if (ipHeap[parent] < ipHeap[leftChild]) {
iLargest = leftChild;
}
}
if (ipHeap[parent] < ipHeap[iLargest]) {
Swap(parent, iLargest, ipHeap);
}
return iLargest;
}
/**
* Replaces the value of the root with the value of the last element of the
* heap.
*
* #param ipHeap
* The heap to have the root replaced.
* #param iSize
* The size of the heap.
*/
void RemoveRoot(int[] ipHeap, int iSize) {
// Put the last element at the root
ipHeap[0] = ipHeap[iSize - 1];
--iSize;
int iLasti = 0;
int i = SwapWithChild(0, ipHeap, iSize);
while (i != iLasti) {
iLasti = i;
i = SwapWithChild(i, ipHeap, iSize);
}
}
/**
* Exchanges the current index value with that of the parent
*
* #param i
* The index of the current value (Child).
* #param ipHeap
* The heap being working with.
* #return
*/
int SwapWithParent(int i, int[] ipHeap) {
if (i < 1) {
return i;
}
int iParent = Parent(i);
if (ipHeap[i] > ipHeap[iParent]) {
Swap(i, iParent, ipHeap);
return iParent;
} else {
return i;
}
}
/**
* Adds an element to the provided heap
*
* #param iNewEntry
* The value being added to the heap.
* #param ipHeap
* The heap to add the new value.
* #param iSize
* The current size of the heap.
*/
void AddElement(int iNewEntry, int[] ipHeap, int iSize) {
ipHeap[iSize] = iNewEntry;
int iLasti = iSize;
int i = SwapWithParent(iLasti, ipHeap);
while (iLasti != i) {
iLasti = i;
i = SwapWithParent(i, ipHeap);
}
}
/**
* Displays the heap to the console in a linear fashion.
*
* #param ipArray
* The heap to be displayed.
* #param iSize
* The current size of the heap.
*/
static void OutputArray(int[] ipArray, int iSize, int verticalBar) {
for (int i = 0; i < iSize; ++i) {
if (i == verticalBar) {
System.out.print("| ");
}
System.out.print(ipArray[i] + " ");
}
System.out.println();
}
/**
* Sorts the heap
*
* #param ipHeap
* The heap that needs to be sorted.
* #param iSize
* The current size of the heap.
*/
static void sortRoot(int[] ipHeap, int iSize) {
// Swap the last element with the root
Swap(0, iSize - 1, ipHeap);
iSize--;
int iLasti = 0;
int i = SwapWithChild(0, ipHeap, iSize);
while (i != iLasti) {
iLasti = i;
i = SwapWithChild(i, ipHeap, iSize);
}
}
static void heapify(int[] a) {
for (int iLast = a.length >> 1; iLast >= 0; iLast--) {
int i = SwapWithChild(iLast, a, a.length);
while (iLast != i) {
iLast = i;
i = SwapWithChild(i, a, a.length);
}
}
}
static void HeapSort2(int[] a, int n) {
heapify(a);
for (int i = 0; i < n; ++i) {
sortRoot(a, n - i);
OutputArray(a, n, n - 1 - i);
System.out.println();
}
}
public static void HeapSort1(int[] a, int n){
int count =n;
//first place a in max-heap order
heapify(a, count);
int end = count - 1;
while(end > 0){
//swap the root(maximum value) of the heap with the
//last element of the heap
int tmp = a[end];
a[end] = a[0];
a[0] = tmp;
//put the heap back in max-heap order
siftDown(a, 0, end - 1);
//decrement the size of the heap so that the previous
//max value will stay in its proper place
end--;
}
}
public static void heapify(int[] a, int count){
//start is assigned the index in a of the last parent node
int start = (count - 2) / 2; //binary heap
while(start >= 0){
//sift down the node at index start to the proper place
//such that all nodes below the start index are in heap
//order
siftDown(a, start, count - 1);
start--;
}
//after sifting down the root all nodes/elements are in heap order
}
public static void siftDown(int[] a, int start, int end){
//end represents the limit of how far down the heap to sift
int root = start;
while((root * 2 + 1) <= end){ //While the root has at least one child
int child = root * 2 + 1; //root*2+1 points to the left child
//if the child has a sibling and the child's value is less than its sibling's...
if(child + 1 <= end && a[child] < a[child + 1])
child = child + 1; //... then point to the right child instead
if(a[root] < a[child]){ //out of max-heap order
int tmp = a[root];
a[root] = a[child];
a[child] = tmp;
root = child; //repeat to continue sifting down the child now
}else
return;
}
}
static void insertion(int[] a, int n) {
//System.out.println("********** INSERTION************");
if (a.length == 0)
return;
for (int i = 0; i < a.length; i++) {
insertionHelper(a, i);
//OutputArray(a, a.length, i);
}
}
/**
* A private helper method for the insertion sorting.
*
* #param iaArray
* Array to be sorted
* #param pointer
* the current element that needs to be inserted in the proper
* order.
*/
private static void insertionHelper(int[] a, int pointer) {
// verify pointer is not at the begining of the array
if (pointer <= 0)
return;
// if pointer' value is smaller than the previous element, we need to
// swap.
while (pointer > 0 && a[pointer] < a[pointer - 1]) {
Swap(pointer, pointer - 1, a);
pointer--;
}
}
public static String myName() {
return "some name";
}
}
The reason that you get stack overflow exception is because you call method QuickSort1 in QuickSort1 and there is a limit when you implement recursive function like that. You can increase your call stack size using -Xss command line arg like:
java -Xss4m

Using a recursive binary search in an InsertInOrder

I'm reading in a text file of unsorted numbers
static void insertInOrder( int[] arr, int cnt, int newVal )
{
int belongs = -( bSearch( arr, 0, arr.length-1, newVal)) - 1;
{
for ( int i = cnt; i >= belongs+1 ; --i)
{
arr[i] = arr[i-1];
}
arr[belongs] = newVal;
}
}
// We do not need to pass in count. The incoming lo and hi define the range
public static int bSearch(int[] a, int lo, int hi, int key)
{
int mid = (lo+hi)/2;
if(lo>hi)
return -1;
else if (a[mid]==key)
return mid;
else if (a[mid]<key)
return bSearch(a, mid+1, hi, key);
else
return bSearch(a, lo, mid-1, key);
}
The binary search is working, but my insertinorder isn't putting the numbers in ascending order and I can't figure out why. It's just printing the list out backwards. And this has to be done using a recursive binary search in an insertinorder.
Have you copied the latest code in to the question ???.
One obvious problem is:
int belongs = -( bSearch( arr, 0, arr.length-1, newVal)) - 1;
the method bSearch returns -1 when a value is not found in the array. This will give an insertion point of -2 when newValue is not found. You need to change bSearch to return both wether the item was found and the position. Two options
Create (and return) a new class
private class FoundResult {
boolean found = true;
int position;
}
When not found; return -hi-1
i.e. in bSearch some thing like:
if(lo>hi)
return -hi-1;
For option 1, the code will be roughly (i have not tested this):
static void insertInOrder( int[] arr, int cnt, int newVal ) {
int belongs = bSearch( arr, 0, arr.length-1, newVal)).position ;
for ( int i = cnt; i >= belongs+1 ; --i) {
arr[i] = arr[i-1];
}
arr[belongs] = newVal;
}
// We do not need to pass in count. The incoming lo and hi define the range
public static FoundResult bSearch(int[] a, int lo, int hi, int key)
{
int mid = (lo+hi)/2;
FoundResult ret;
if(lo>hi) {
ret = new FoundResult();
ret.found = false;
ret.position = hi;
return ret;
} else if (a[mid]==key) {
ret = new FoundResult();
ret.position = hi;
return ret;
} else if (a[mid]<key) {
return bSearch(a, mid+1, hi, key);
} else {
return bSearch(a, lo, mid-1, key);
}
For option 2 the code is roughly:
static void insertInOrder( int[] arr, int cnt, int newVal ) {
int belongs = bSearch( arr, 0, arr.length-1, newVal)) ;
if (belongs < 0) {
belongs = -1 - belongs ;
}
for ( int i = cnt; i >= belongs+1 ; --i) {
arr[i] = arr[i-1];
}
arr[belongs] = newVal;
}
// We do not need to pass in count. The incoming lo and hi define the range
public static int bSearch(int[] a, int lo, int hi, int key)
{
int mid = (lo+hi)/2;
FoundResult ret;
if(lo>hi) {
return - hi - 1;
} else if (a[mid]==key) {
return hi;
} else if (a[mid]<key) {
return bSearch(a, mid+1, hi, key);
} else {
return bSearch(a, lo, mid-1, key);
}

Categories