How to Insertion Sort? - java

What is missing?
less a little
It's almost done
Also is there a way to make it faster?
thanks
public class InsertionSort {
public static void main(String[] argv) {
int[] data = {4, 1, 7, 8, 9, 3, 2};
sort(data);
for (int i = 0; i < data.length; i++) {
System.out.println(data[i]);
}
}
public static void sort(int[] data) {
int j, pivot;
// insert data[i] to sorted array 0 ~ i - 1
// begins from i = 1, because if the array has only one element then it must be sorted.
for (int i = 1; i < data.length; i++) {
pivot = data[i];
for (j = i - 1; j >= 0 && data[j] > pivot; j--) // shift data[j] larger than pivot to right
{
data[j+1] = data[j];
}
}
}
}

Your code have a problem when you are interchanging the values between data[j+1] and data[j]. You overwriting the value from data[j+1], without to keep it in a temporal variable and put it in data[j].
public class InsertionSort {
public static void main(String[] argv) {
int[] data = {4, 1, 7, 8, 9, 3, 2};
sort(data);
for (int i = 0; i < data.length; i++) {
System.out.println(data[i]);
}
}
public static void sort(int[] data) {
int tmp, pivot;
// insert data[i] to sorted array 0 ~ i - 1
// begins from i = 1, because if the array has only one element then it must be sorted.
for (int i = 1; i < data.length; i++) {
pivot = data[i];
for (int j = i - 1; j >= 0 && data[j] > pivot; j--) // shift data[j] larger than pivot to right
{
tmp = data[j + 1];
data[j + 1] = data[j];
data[j] = tmp;
}
}
}
}
As #dan1st suggest, try to use quicksort if you want a better performance. A good explanation of the quicksort algorithm and it's Java implementation you could find here

Related

Check whether an element has a successor in java Array

I am trying to check whether an element of array has a successor.in other words, make the Ascending sublist to 0 and the rest to 1. the first element of the inputArray should be ignored
if yes then the both element should be 0 if not then 1. For example: for the input
int[] arr = {1,8,1,9,10};
the output should be [1,1,1,0,0]
another example: for the input int[] arr = {1,2,3,9,100}; should the output be: [1,0,0,1,1]
This is my try, but it does not work as expected. Where am i making failur?
public class HelloWorld {
public static void main(String[] args) {
int[] arr = { 1, 8, 1, 9, 10 };
int[] listOutput;
for (int i = 1; i<arr.length - 1; i++) {
if (arr[i] - arr[i + 1] == -1) {
arr[i] = 0;
arr[i + 1] = 0;
} else {
arr[i] = 1;
}
}
System.out.println("Hello World");
for (int i = 0; i<arr.length; i++) {
System.out.println(arr[i]);
}
}
}
public static void main(String[] args) {
int[] arr = { 1, 8, 1, 9, 10 };
// assume arr.length >= 2
boolean asc = arr[1] - arr[0] == 1;
for (int i = 1; i < arr.length - 1; i++) {
if (arr[i + 1] - arr[i] == 1) {
arr[i] = 0;
asc = true;
} else {
if (asc) {
asc = false;
arr[i] = 0;
}
else {
arr[i] = 1;
}
}
}
arr[arr.length - 1] = asc ? 0 : 1;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
This will replace each ascending (by 1) sublist of size greater than 1 with 0s, and will replace each remaining element with 1 (besides the first element which remains unchanged).
You're looping the array from 1 instead of from 0.

split array into two equal subarray where index is selected

I need to return an index of the element where the sum of the elements on the left is equal to the sum of the elements on the right. e.g for the array [-3, 8, 3, 1, 1, 3], the return value is index 2 since the sum of the elements to the left of the first 3 ([-3, 8]) is the same as the sum of elements to its right ([1, 1, 3]).
So I started by doing a liner-search function to find the intended index,
then after that i attempted to split the array left and right of the selected index but had no success doing so
I haven't had much success getting it to work
//linear-search portion,x is the index selected to be split point
public static int findindex(int arr[], int x) {
//if array is null
if (arr == null) {
return -1;
}
//find array length
int len = arr.length;
int i = 0;
//traverse the array
while (i < len) {
//if the i-th element is is x then return the index
if (arr[i] == x) {
return i;
} else {
i = i + 1;
}
}
//splint array portion,returns index if not possible
int leftsum = 0;
//treverse array elements
for (int i = 0; i < x; i++) {
//adds current elements to left
leftsum += arr[i];
//find sum of remader the array elements to rightsum
int rightsum = 0;
for (int j = i + 1; j < x; J++)
rightsum += arr[j];
//split pint index
if (leftsum == rightsum)
return i + 1;
}
//if not possible return
return -1;
}
// driver code
public static void main(String[] args) {
int[] array1 = { -3, 8, 3, 1, 1, 3 };
System.out.println(findindex(array1));
}
You can use the below code for solve the problem
static void Main(string[] args)
{
int[] array1 = {-3, 8, 3, 1, 1, 3}; // { -3, 8, 3, 1, 1, 3, 6, 1, 19 };
int indexPosition = GetIndex(array1);
if (indexPosition != -1)
{
Console.WriteLine(indexPosition);
}
}
static int GetIndex(int[] param)
{
if (param.Length < 0) return -1;
int leftSum = 0, rightSum = 0; int rightIndex = param.Length - 1;
for (int i = 0; i < param.Length; i++)
{
if (i < rightIndex)
{
if (leftSum > rightSum)
{
rightSum += param[rightIndex];
rightIndex -= 1;
}
else
{
if (i < rightIndex)
{
leftSum += param[i];
}
}
}
else
{
rightSum += param[rightIndex]; // if you are looking for only index position you can comment this line,
//variable rightSum and leftSum will give you the sum of left and right side of the array
rightIndex -= 1;
break;
}
}
return rightIndex;
}
Hope this helps .
Your code has two problems. One is that the variable i is defined two times in the same method. Another problem is that you only provide one input parameter and not two. I don't even know what parameter x should be and therefore also removed it from my improved version. I also removed the while loop as I don't understand what you tried to do there. Anyways here is my version of the code:
public static int findindex(int arr[]) {
if (arr == null) {
return -1;
}
int len = arr.length;
int leftsum = 0;
for(int i = 0; i < len; i++)
{
leftsum += arr[i];
int rightsum = 0;
for(int j = i+2; j < len; j++)
rightsum += arr[j];
if(leftsum == rightsum)
return i+1;
}
return -1;
}
public static void main(String[] args) {
int[] array1 = {-3, 8, 3, 1, 1, 3};
System.out.println(findindex(array1));
}
When I removed everything unneccessary from your code the only bug was that you should have initialized j with i+2, because you don't want to include the element at the index itself and only the right side, if I understood the requirements of your code correctly.

merging 3 sorted arrays

public class array12 {
static void merge_sort(int A[], int start, int end) {
if (end - start > 1) {
int middle1 = (2 * start + end + 1) / 3 - 1;
int middle2 = 2 * middle1 - start + 1;
merge_sort(A, start, middle1);
merge_sort(A, middle1 + 1, middle2);
merge_sort(A, middle2 + 1, end);
merge(A, start, middle1, middle2, end);
}
}
static void merge(int[] x, int start, int middle1, int middle2, int end) {
int n1 = middle1 - start + 1;
int n2 = middle2 - middle1;
int n3 = end - middle2;
int left[] = new int[n1]; // defining and initialising three arrays .
int mid[] = new int[n2];
int right[] = new int[n3];
for (int i = 0; i < left.length; i++) {
left[i] = x[i + start];
}
for (int i = 0; i < mid.length; i++) {
mid[i] = x[i + middle1 + 1];
}
for (int i = 0; i < right.length; i++) {
right[i] = x[i + middle2 + 1];
}
int i = 0;
int j = 0;
int k = 0;
int c = start;
// finding minimum element from the three arrays .
while (i < n1 && j < n2 && k < n3) {
if (left[i] <= mid[j] && left[i] <= right[k]) {
x[c] = left[i];
i++;
c++;
} else if (mid[j] <= left[i] && mid[j] <= right[k]) {
x[c] = mid[j];
j++;
c++;
} else {
x[c] = right[k];
k++;
c++;
}
}
// now only two arrays are left to be compared
while (i < n1 && j < n2) {
if (left[i] <= mid[j]) {
x[c] = left[i];
i++;
c++;
} else {
x[c] = mid[j];
j++;
c++;
}
}
while (j < n2 && k < n3) {
if (mid[j] <= right[k]) {
x[c] = mid[j];
j++;
c++;
} else {
x[c] = right[k];
k++;
c++;
}
}
while (i < n1 && k < n3) {
if (left[i] <= right[k]) {
x[c] = left[i];
i++;
c++;
} else {
x[c] = right[k];
k++;
c++;
}
}
// now only single array is left out of left[] , mid[] and right[].
while (i < n1) {
x[c] = left[i];
i++;
c++;
}
while (j < n2) {
x[c] = mid[j];
j++;
c++;
}
while (k < n3) {
x[c] = right[k];
k++;
c++;
}
System.out.println("");
// printing array elements after every merge operation .
for (int e = 0; e < x.length; e++) {
System.out.print(x[e] + " ");
}
}
public static void main(String[] args) {
int[] x = new int[9];
for (int i = 0; i < x.length; i++) {
x[i] = x.length - i;
}
System.out.println("initial array is : ");
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
System.out.println("");
merge_sort(x, 0, x.length - 1);
System.out.println("");
System.out.println("");
System.out.println(" sorted array is : ");
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
}
}
I am trying to merge 3 sorted arrays . I have been able to develop code for array size equal to power of 3 . I am unable to implement it with some other array size . I have tried to change values of middle1 and middle2 but am experiencing serious trouble . Setting their values is the main concern . Merging step is quite simple and is not causing problems .
What changes are required in my code so that it may work for any array size ? Can it be implemented using this approach ? I dont want size of any of the three arrays , left[] , mid[] and right[] to be zero at any time .
Please help .
Here's a similar answer to YCF_L's, but simplified (still uses Java 8):
public static int[] sortMultipleArrays(int[]... arrays) {
return Arrays.stream(arrays)
.flatMapToInt(Arrays::stream)
.sorted()
.toArray();
}
Output:
[1, 2, 3, 5, 6, 7, 9, 10, 12, 13, 17, 20, 21, 24]
I don't follow your merge code. It seems overly complicated.
Here is a method for merging an unlimited number of sorted arrays, each a varying size.
private static int[] mergeSortedArrays(int[]... arrays) {
int totalLen = 0;
for (int[] arr : arrays)
totalLen += arr.length;
int[] idx = new int[arrays.length];
int[] merged = new int[totalLen];
for (int i = 0; i < totalLen; i++) {
int min = 0, minJ = -1;
for (int j = 0; j < arrays.length; j++)
if (idx[j] < arrays[j].length)
if (minJ == -1 || min > arrays[j][idx[j]]) {
min = arrays[j][idx[j]];
minJ = j;
}
merged[i] = min;
idx[minJ]++;
}
return merged;
}
Test
int[] a = { 3, 5, 9, 13, 17, 21 };
int[] b = { 2, 10, 20 };
int[] c = { 1, 7, 12, 24 };
int[] d = { 6 };
int[] merged = mergeSortedArrays(a, b, c, d);
System.out.println(Arrays.toString(merged));
Output
[1, 2, 3, 5, 6, 7, 9, 10, 12, 13, 17, 20, 21, 24]
If using class "Integer" instead of primitive int is not a problem you can use this, basically first do the merge and after sort them: you can do the call Arrays.sort even in the same method and call it mergeAndSort, if you want...
import java.util.Arrays;
public class Main {
public static Integer[] merge(Integer[]... arrays) {
int count = 0;
for (Integer[] array : arrays) {
count += array.length;
}
Integer[] mergedArray = (Integer[]) java.lang.reflect.Array.newInstance(arrays[0][0].getClass(), count);
int start = 0;
for (Integer[] array : arrays) {
System.arraycopy(array, 0, mergedArray, start, array.length);
start += array.length;
}
return mergedArray;
}
public static void main(String[] args) {
Integer[] array1 = {3, 5, 6, 7, 78, 100};
Integer[] array2 = {5, 6, 7, 8, 9};
Integer[] array3 = {2, 6, 7};
Integer[] merged1 = merge(array1, array2);
Arrays.sort(merged1);
Integer[] merged2 = merge(array1, array2, array3);
Arrays.sort(merged2);
printArray(merged1);
printArray(merged2);
}
public static void printArray(Integer[] x) {
System.out.println("--ToString--");
for (Integer var : x) {
System.out.println(var);
}
System.out.println("----");
}
}

Java Selection Sort Modification

So I made this selection sort code, but I want it to increment one loop of the sort each time the function is called.
So I thought okay. Why not just remove the outer for loop and replace index with a static variable up top and increment it each time the function finishes its operations. But that just messed up the sort really badly. Can someone help?
Question: How do I go through the sort one step at a time each time the function is called?
I don't want it to sort the entire thing all at once
private static void selectionSort(int[] array) {
for (int index = 0; index < array.length; index++) {
int currentMin = array[index];
int indexOfMin = index;
for(int j = index+1; j < array.length; j++) {
if(array[j] < currentMin) {
currentMin = array[j];
indexOfMin = j;
}
}
swap(array, index, indexOfMin);
}
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
Why wouldn't global variable do the job? Do you wanna post your solution and we can take a look? Or you can also just pass the starting index to the function and call it with incremental index every time the button is pressed.
private static void selectionSort(int fromIndex, int[] array) {
int currentMin = array[fromIndex];
int indexOfMin = fromIndex;
for(int j = fromIndex+1; j < array.length; j++) {
if(array[j] < currentMin) {
currentMin = array[j];
indexOfMin = j;
}
}
swap(array, fromIndex, indexOfMin);
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
Then in main, call it like this:
for (int fromIndex = 0; fromIndex < array.length; fromIndex++) {
// Stop here and wait for button click.
selectionSort(fromIndex, array);
}
call function
Collections.sort(array, new SortData());
in SortData.java
import java.util.Comparator;
import tg.cw.pd.model.ModelcurrentMin;
public class SortData implements Comparator<Object>
{
public int compare(Object o1, Object o2)
{
int result;
String desc1 = ((ModelcurrentMin)o1).getcurrentMin();
String desc2 = ((ModelcurrentMin)o2).getcurrentMin();
result = desc1.compareTo(desc2); //asc
return result;
}
}
Check this one..
public static void main(String[] args) {
int[] array = new int[]{3, 4, 2, 7, 1, 5, 6};
System.out.println(Arrays.toString(array)); //[2, 4, 3, 7, 5, 1, 6]
selectionSort(array);
System.out.println(Arrays.toString(array)); //[1, 4, 3, 7, 5, 2, 6]
selectionSort(array);
System.out.println(Arrays.toString(array)); //[1, 2, 3, 7, 5, 4, 6]
selectionSort(array);
System.out.println(Arrays.toString(array)); //[1, 2, 3, 4, 5, 7, 6]
selectionSort(array);
System.out.println(Arrays.toString(array)); //[1, 2, 3, 4, 5, 6, 7]
}
private static void selectionSort(int[] array) {
for (int index = 0; index < array.length; index++) {
int currentMin = array[index];
int indexOfMin = index;
boolean swapNeeded = false;
for (int j = index + 1; j < array.length; j++) {
if (array[j] < currentMin) {
currentMin = array[j];
indexOfMin = j;
swapNeeded = true;
}
}
if (swapNeeded) {
swap(array, index, indexOfMin);
return;
}
}
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
selectionSort() has to be called 7 times to sort this array.
But if you consider array like {3, 5, 1, 4, 7, 6, 2}, 3rd and 4rd indices of the array are already in the sorted positions. Therefore, selectionSort() has to be called only 5 times.

Insertion Sort not working properly

package sort;
public class InsertionSort {
public static void main(String[] args) {
int[] input ={5,3,5,3,2,1}; // the input to be sorted.
int key; // the value that will be put into its place in the pass
int j = 0; // indexes to be
int i = 0; // used for sorting
for(j = 1; j < input.length; j++){
key = input[j];
for(i = j-1; i >= 0; i--){ // Look for a proper place for the key
if(i-1 < 0){
if(input[i] > key){ // Have you found that place ?
for(int k = j;k > i; k--){ // Begin shifting
input[k] = input[k-1];
} // Done Shifting
input[i] = key; // Insert the key in proper place
break;
}
}else{
if(input[i] > key && input[i-1] < key){ // Have you found that place ?
for(int k = j;k > i; k--){ // Begin shifting
input[k] = input[k-1];
} // Done Shifting
input[i] = key; // Insert the key in proper place
break;
}
}
}
}
for(int each : input){
System.out.println(each);
}
}
}
The problem is that if my input has repeated numbers, sorting fails.
For int[] input ={5,3,5,3,2,1};, I get 1 2 3 5 5 3
For non-repeated numbers, sorting works fine.
What is wrong here ?
public static void main(String[] args) {
int[] input = {12, 21, 21, 1, 4, 5, 66, 74, 0, -2, 5, 3, 5, 3, 2, 1}; // the input to be sorted.
int key; // the value that will be put into its place in the pass
int j = 0; // indexes to be
int i = 0; // used for sorting
for (i = 1; i < input.length; i++) {
key = input[i];
j = i;
while (j > 0 && input[j - 1] > key) {
input[j] = input[j - 1];
j--;
}
input[j] = key;
}
for (int each : input) {
System.out.println(each);
}
}

Categories