Insertion Sort not working properly - java

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);
}
}

Related

How to Insertion Sort?

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

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.

How to find number of tuples whose sum is equal or less than a given number?

I'm designing an algorithm to find the number of tuples whose sum is equal or less than a given number. I know other ways of solving it using LinkedList, so, not looking for that solution. I just want to traverse through the array and count the possible matches that satisfy the relation. I come up so far,
public static int numberOfPairs(int[] a, int k ){
int len = a.length;
if (len == 0){
return -1;
}
Arrays.sort(a);
int count = 0, left = 0, right = len -1;
while( left < right ){
if ( a[left] + a[right] <= k ){
// System.out.println(a[left] + "\t" + a[right]);
count++;
/*may be the same numbers will also satisfy the relation*/
if ( a[left] + a[left+1] <= k) {
count ++;
// System.out.println(a[left] + "\t"+a[left+1]);
}
/*now, use iteration to traverse the same elements*/
while (a[left] == a[left+1] && left < len-1 ){
left++;
}
/*may be the same numbers will also satisfy the relation*/
if ( a[right] + a[right-1] <= k) {
count ++;
// System.out.println(a[right] +"\t"+ a[right-1]);
}
/*now, use iteration to traverse
the same elements*/
while ( a[right] == a[right-1] && right >1 ){
right-- ;
}
}
// traverse through the array
left++;
right--;
}
return count;
}
This is not providing the correct solution, say, if I pass array and number as following,
int [] arr = { 3, 3, -1, 4, 2,5, 5, 1};
System.out.println(numberOfPairs(arr, 8));
The correct solution will be 15 pairs as following,
{
{-1,1}, {-1,2} , {3,-1}, {-1,4 }, {-1,5},
{2,1},{3,1 },{4,1}, { 5,1},
{3,2 },{4,2}, {2,5 },
{3,4 } , {3,5 },
{3,3}
}
How can I improve my code ? thanks.
Note: the other way I solve it using LinkedList is as following,
public static int numberOfPairs10(int[] arr, int sum){
/*1.can be the same values of i
2. can be the same valus of j for the same i*/
List<Integer> li = new ArrayList<Integer>();
List<Integer> lj;
int count = 0;
for ( int i =0; i < arr.length -1 ; i++){
if (li.contains(arr[i]) )
continue;
lj = new ArrayList<Integer>();
for (int j = i+1; j < arr.length; j++){
if (lj.contains(arr[j]))
continue;
// if ( arr[i]+ arr[j] <= sum){
if ( arr[i]+ arr[j] == sum){
count++;
lj.add(arr[j]);
}
}
li.add(arr[i]);
}
return count;
}
This is tested with just
int [] arr = { 3, 3, -1, 4, 2,5, 5, 1};
numberOfPairs(arr, 8);
and here is codes
public static int numberOfPairs(int[] a, int k ) {
int len = a.length;
int counter = 0;
boolean isCheckedLeft = false;
boolean isCheckedRight = false;
int i, j, h;
Arrays.sort(a);
for (i = 0; i < len; i++) {
isCheckedLeft = false;
for (j = i - 1; j >= 0; j--) {
if (a[i] == a[j]) {
isCheckedLeft = true;
break;
}
}
if (isCheckedLeft) {
continue;
}
for (j = i + 1; j < len; j++) {
isCheckedRight = false;
for (h = j - 1; h > i; h--) {
if (a[j] == a[h]) {
isCheckedRight = true;
break;
}
}
if (isCheckedRight) {
continue;
}
System.out.print("("+a[i]+", "+a[j]+") ");
if (a[i] + a[j] <= k) {
counter++;
}
}
}
return counter;
}
If you are not too worried about performance then you could just find all unique combinations and then filter according to your condition. For example, using Java 8 streams:
public int numberOfPairs(int[] values, int maxVal) {
return IntStream.range(0, values.length)
.flatMap(i1 -> IntStream.range(i1 + 1, values.length)
.map(i2 -> Arrays.asList(values[i1], values[i2])))
.distinct().filter(l -> l.stream().sum() <= maxVal).count();
}

How do I find the largest negative value in an array with both positive and negative values?

I need to return the greatest negative value, and if there are no negative values, I need to return zero.
Here is what I have:
public int greatestNegative(int[] list) {
for (int i = 0; i < list.length; i++) {
if (list[i] < 0)
negativeNumbers ++;
}
int j = list.length - 1;
while (j >= 0) {
if (list[j - negativeNumbers] < 0) {
list[j] = 0;
list[j - 1] = list[j - negativeNumbers];
negativeNumbers--;
j--;
}
else{
list[j] = list[j - negativeNumbers];
j--;
}
}
}
You just need to think of this problem as 2 steps:
Only consider negative values in list[].
In the loop within negative values, update current result if (result == 0) or (value > result).
Code:
public int greatestNegative(int[] list) {
int result = 0;
for (int i = 0; i < list.length; i++) {
if (list[i] < 0) {
if (result == 0 || list[i] > result) {
result = list[i];
}
}
}
return result;
}
Just go about finding the max number with an added condition.
public static int greatestNegative(int[] list) {
int max = Integer.MIN;
boolean set = false;
for (int i = 0; i < list.length; i++) {
if (list[i] < 0 && list[i] > max) {
max = arr[i];
set = true;
}
}
if (!set)
max = 0;
return max;
}
Here is the code which return the smallest negative number
public static int greatestNegative(int[] list) {
int negativeNumbers = 0;
for (int i = 0; i < list.length; i++) {
if (list[i] < 0 && list[i] < negativeNumbers)
negativeNumbers = list[i];
}
return negativeNumbers;
}
Input : 1, 2, -3, 5, 0, -6
Output : -6
Input : 1, 2, 3, 5, 0, 6
Output : 0
If you need the greatest negative number then sort array thin search for first negative number
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int arr[] = { 2, 4, 1, 7,2,-3,5,-20,-4,5,-9};
System.out.println(greatestNegative(arr));
}
private static int greatestNegative(int[] arr) {
Arrays.sort(arr);
for (int i = arr.length - 1; i >= 0; i--) {
if (isNegative (arr[i])) {
return arr[i];
}
}
return 0;
}
private static boolean isNegative (int i) {
return i < 0;
}
}
Output : -3
Please check following code, which will
first calculate small number from array,
then check is it positive? if yes return 0 else return negative.
public static int greatestNegative(int[] list)
{
int negativeNumbers = Integer.MAX_VALUE;
for (int i = 0; i < list.length; i++) {
if (list[i] < negativeNumbers)
negativeNumbers = list[i];
}
if(negativeNumbers >=0)
return 0;
else
return negativeNumbers;
}
You have to try this....
public int greatestNegative(int[] list) {
int negNum = 0;
for(int i=0; i<list.length; i++) {
if(list[i] < negNum){
negNum = list[i];
}
}
return negNum;
}
public int largNegative(int[] list) {
int negNum = 0;
boolean foundNeg = false;
for(int i=0; i<list.length; i++) {
if(list[i] < negNum && !foundNeg){
foundNeg = true;
negNum = list[i];
} else if(foundNeg && list[i] < 0 && negNum < list[i]) {
negNum = list[i];
}
}
return negNum;
}
Start by setting your "maxNegative" value to 0. Then assign the first negative number you come across. After that, only assign negative numbers that are higher. If there are no negative numbers, then your "maxNegative" will still be zero.
public static void main(String[] args) {
int arr[] = {2, -1, 4, 1, 0, 7, 2, -3, 5, 9, -4, 5, -9};
int maxNegative = 0;
for (int i = 0; i < arr.length; i++) {
if (maxNegative == 0 && arr[i] < maxNegative) {
// Set the first negative number you come across
maxNegative = arr[i];
} else if (maxNegative < arr[i] && arr[i] < 0) {
// Set greater negative numbers
maxNegative = arr[i];
}
}
System.out.println(maxNegative);
}
Results:
-1
Java 8
Then there are streams, that allow you to do this with one line of code.
public static void main(String[] args) {
int arr[] = {2, 4, 1, 0, 7, 2, -3, 5, 9, -4, 5, -9};
int maxNegative = Arrays.stream(arr).filter(a -> a < 0).max().orElse(0);
System.out.println(maxNegative);
}
Results:
-3

Categories