-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
1869 lines (1552 loc) · 67.9 KB
/
Copy pathmain.c
File metadata and controls
1869 lines (1552 loc) · 67.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//
// main.c
// Array
//
// Created by jjkhan on 7/6/21.
//
#include <stdio.h>
#include <stdlib.h> // For malloc function
#include <math.h> // For floor operations in BinarySearch
#include <stdbool.h> // for bool type
#include <string.h> // for memset
// creating a struct for an array
struct dynamicArray{
int *A;
int size;
int length;
};
struct staticArray{
int A[20];
int size;
int length;
};
// Member functions
struct dynamicArray createDynamicStruct(void);
void staticArray_Display(struct staticArray arr);
void dynamicArray_Display(struct dynamicArray arr);
void dynamicArray_append(struct dynamicArray *arr, int value);
void staticArray_append(struct staticArray *arr, int value);
void staticArray_insertAtIndex(struct staticArray *arr, int index, int value);
void dynamicArray_insertAtIndex(struct dynamicArray *arr, int index, int value);
int staticArray_deleteAtIndex(struct staticArray *arr, int index);
int dynamicArray_deleteAtIndex(struct dynamicArray *arr, int index);
int staticArray_linearSearch(struct staticArray *arr, int value);
int dynamicArray_linearSearch(struct dynamicArray *arr, int value);
int Recursive_BinarySearch(int arr[], int low, int high, int key);
int Iterative_BinarySearch(int arr[], int length, int key);
void left_shift(int *arr, int length);
void right_shift(int *arr, int length);
void rotate_left(int *arr, int length);
void rotate_right(int *arr, int length);
void reverse_array(int *arr, int length);
void staticArray_insert_sortedArray(struct staticArray *arr, int value);
void dynamicArray_insert_sortedArray(struct dynamicArray *arr, int value);
bool isSorted(int arr[], int length);
void move_negative_to_left(int *arr, int length);
int * mergeArrays(int *arr1, int arr1_length, int *arr2, int arr2_length);
// Set Operations on array - an Array can hold a set of elements
// Union: All the elements of arr1 and arr2, without duplicates
// Intersection: Common elements of arr1 and arr2.
// Difference: Arr1-Arr2, the elements that are in arr2 but not in arr1?
// Set membership: Searching if an element is part of the set
//
// The two sets could be sorted or unsorted. If the two sets are sorted,
// all the set operations below can be implemented using the idea behind merge of
// two arrays. For unsorted sets, there are different ways to do it. Regardless of
// if the two sets are sorted or unsorted, the result of a set operation would
// require another array to return results.
struct dynamicArray* union_of_unsorted_sets(int *arr1, int arr1_len, int *arr2, int arr2_len);
struct dynamicArray* union_of_sorted_sets(int *arr1, int arr1_len, int *arr2, int arr2_len);
struct dynamicArray* intersection_of_unsorted_sets(int *arr1, int arr1_len, int *arr2, int arr2_len);
struct dynamicArray* intersection_of_sorted_sets(int *arr1, int arr1_len, int *arr2, int arr2_len);
struct dynamicArray* difference_of_unsorted_sets(int *arr1, int arr1_len, int *arr2, int arr2_len);
struct dynamicArray* difference_of_sorted_sets(int *arr1, int arr1_len, int *arr2, int arr2_len);
bool is_memeber_of_unsorted_set(int *arr, int len, int value);
bool is_memeber_of_sorted_set(int *arr, int len, int value);
// Finding missing elements in an array
void find_single_missing_element_of_n_natural_numbers(int *arr, int len); // Sorted array
void find_single_missing_element_of_natural_numbers(int *arr, int len); // Sorted array
void find_multiple_missing_element_of_natural_numbers(int *arr, int len); // Sorted array
void find_all_missing_numbers(int *arr, int len, int lowestNumber, int highestNumber); // could be used with both sorted and unsorted list of numbers
// Finding duplicates in an array
void find_duplicates_sorted_array_not_using_hashtable(int *arr, int len);
void count_duplicates_sorted_array_not_using_hashtable(int *arr, int len);
void count_duplicates_sorted_array_using_hashtable(int *arr, int len);
void count_duplicates_unsorted_array_using_hashtable(int *arr, int len);
// Find a pair in given array that add to given sum
void find_pair_for_given_sum(int *arr,int len, int sum); // works for both sorted and unsorted list -> O(n)
void find_pair_give_sorted_array(int *arr, int len, int sum); // Only works for sorted array -> O(n)
// Find max and min in an array in single scan
void find_max_min_in_single_scan(int *arr, int len);
// Programs
void print_Array(int* arr, int length);
void append_to_array(void);
void insert_at_index(void);
void delete_at_index(void);
void linear_Search(void);
void binary_Search(void);
void shift_array(void);
void rotate_array(void);
void reverse(void);
void sorted_Array_insert(void);
void check_if_sorted(void);
void separate_pos_neg_values(void);
void merge_two_arrays(void);
void get_union_of_unsorted_sets(void);
void get_union_of_sorted_sets(void);
void get_intersection_of_unsorted_sets(void);
void get_intersection_of_sorted_sets(void);
void get_difference_of_unsorted_sets(void);
void get_difference_of_sorted_sets(void);
void search_unsorted_list(void);
void search_sorted_list(void);
void missing_elements(void);
void find_duplicates(void);
void find_pairs_for_given_sum(void);
void find_min_max(void);
int main(int argc, const char * argv[]) {
// insert code here...
find_min_max();
return 0;
}
void find_min_max(void){
int arr1[]={1,3,4,5,6,7,8};
int arr2[]={-10,11,45,100,22000,556,-1000};
print_Array(arr1, 7);
find_max_min_in_single_scan(arr1, 7);
print_Array(arr2, 7);
find_max_min_in_single_scan(arr2, 7);
}
// Test passed.
void find_pairs_for_given_sum(void){
int arr1[]={1,3,4,5,6,7,8}; // sorted
int arr2[]={3,5,2,7,6,10}; // unsorted
print_Array(arr1, 7);
find_pair_for_given_sum(arr1, 7, 10);
print_Array(arr2, 6);
find_pair_for_given_sum(arr2, 7, 10);
print_Array(arr1, 7);
find_pair_give_sorted_array(arr1, 7, 10);
}
// Test passed
void find_duplicates(void){
int arr1[]={1,2,3,4,5,5,6,7,8,9,9,9};
int arr2[]={2,5,1,1,7,9,8,4,4,8};
print_Array(arr1, 12);
count_duplicates_sorted_array_not_using_hashtable(arr1, 12);
find_duplicates_sorted_array_not_using_hashtable(arr1, 12);
count_duplicates_sorted_array_using_hashtable(arr1,12);
print_Array(arr2, 10);
count_duplicates_unsorted_array_using_hashtable(arr2,10);
}
// Tests passed;
void missing_elements(void){
int arr1[] = {1,2,3,4,5,6,8,9,10};
int arr2[] = {6,7,8,9,11,12,13};
int arr3[] ={6,7,9,10,13,16,20};
print_Array(arr1, 9);
find_single_missing_element_of_n_natural_numbers(arr1, 9);
print_Array(arr2, 7);
find_single_missing_element_of_natural_numbers(arr2, 7);
print_Array(arr3, 7);
find_multiple_missing_element_of_natural_numbers(arr3, 7);
print_Array(arr3, 7);
find_all_missing_numbers(arr3, 7, 6, 20);
}
// Tests: Passed
void search_sorted_list(void){
int arr1[]={3,5,7,9,11};
print_Array(arr1, 5);
printf("Search for %d, result: %d\n",1, is_memeber_of_unsorted_set(arr1, 5, 1));
printf("Search for %d, result: %d\n",9, is_memeber_of_unsorted_set(arr1, 5, 9));
}
// Tests: Passed
void search_unsorted_list(void){
int arr1[]={1,5,3,11,15};
print_Array(arr1, 5);
printf("Search for %d, result: %d\n",11, is_memeber_of_unsorted_set(arr1, 5, 11));
printf("Search for %d, result: %d\n",2, is_memeber_of_unsorted_set(arr1, 5, 2));
}
// Tests: Same size sets - passed
// Set1 smaller than set2 - passed
// Set1 bigger than set2 - Passed
void get_difference_of_sorted_sets(void){
int arr1[]={3,5,7,9,11,20};
int arr2[]={1,3,5,11,15};
int arr3[]={1,7,11};
print_Array(arr1, 6);
print_Array(arr2, 5);
struct dynamicArray *result = difference_of_sorted_sets(arr1, 6, arr2, 5);
dynamicArray_Display(*result);
}
// Tests: Same size sets - passed
// Set1 smaller than set2 - passed
// Set1 bigger than set2 - Passed
void get_difference_of_unsorted_sets(void){
int arr1[]={5,3,2,15,1,25,16};
int arr2[]={1,5,3,11,15};
int arr3[]={5,56,45};
print_Array(arr1, 7);
print_Array(arr2, 5);
struct dynamicArray *result = difference_of_unsorted_sets(arr1, 7, arr2, 5);
dynamicArray_Display(*result);
}
// Tests: Same size sets - passed
// Different size sets - passed
void get_intersection_of_sorted_sets(void){
int arr1[]={3,5,7,9,11};
int arr2[]={1,3,5,11,15};
int arr3[]={1,5,15};
print_Array(arr3, 3);
print_Array(arr2, 5);
struct dynamicArray *result = intersection_of_unsorted_sets(arr3, 3, arr2, 5);
dynamicArray_Display(*result);
}
// Tests: Same size sets - passed
// Different size sets - passed
void get_intersection_of_unsorted_sets(void){
int arr1[]={5,3,2,15,1};
int arr2[]={1,5,3,11,15};
int arr3[]={5,56,15};
print_Array(arr3, 3);
print_Array(arr1, 5);
struct dynamicArray *result = intersection_of_unsorted_sets(arr3, 3, arr1, 5);
dynamicArray_Display(*result);
}
// Test case: Same size sorted sets: Passed
// Different size sorted sets: Passed
void get_union_of_sorted_sets(void){
int arr1[]={3,5,7,9,11};
int arr2[]={1,3,5,11,15};
int arr3[]={0,9,10};
print_Array(arr1, 5);
print_Array(arr3, 3);
struct dynamicArray *union_result = union_of_sorted_sets(arr1, 5, arr3, 3);
dynamicArray_Display(*union_result);
}
// Test passed with both: Same size unsorted arrays & different sizes
void get_union_of_unsorted_sets(void){
// Create two unsorted arrays
int arr1[]={3,5,10,4,6};
int arr2[]={12,4,7,2,5};
int arr3[]={12,4,6};
print_Array(arr3, 3);
print_Array(arr2, 5);
struct dynamicArray *union_result = union_of_unsorted_sets(arr3, 3, arr2, 5);
dynamicArray_Display(*union_result);
}
void merge_two_arrays(void){
// the two arrays you want to merge have to be sorted.
int arr1[] ={ 1,3,5,7,9,11};
int arr2[] ={ 1,4,6,10};
int *mergeArray = mergeArrays(arr1, 6, arr2, 4);
print_Array(mergeArray, 10);
}
void separate_pos_neg_values(void){
// Statically allocated memory
struct staticArray arr ={{1,6,-8,9,-5, -2,4}, 20, 7};
staticArray_Display(arr);
move_negative_to_left(arr.A, 7);
staticArray_Display(arr);
// Dynamic array
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
move_negative_to_left(arr2.A, 7);
dynamicArray_Display(arr2);
}
void check_if_sorted(void){
// Statically allocated memory
struct staticArray arr ={{1,1,9,10}, 20, 4};
printf("Is the array sorted? %d\n", isSorted(arr.A, 4));
// Dynamic array
struct dynamicArray arr2 = createDynamicStruct();
printf("Is the array sorted? %d\n", isSorted(arr2.A, 4));
}
void sorted_Array_insert(void){
// Statically allocated memory
struct staticArray arr ={{1,6,8,9}, 20, 4};
staticArray_Display(arr);
staticArray_insert_sortedArray(&arr, 0);
staticArray_Display(arr);
staticArray_insert_sortedArray(&arr, -1);
staticArray_Display(arr);
staticArray_insert_sortedArray(&arr, 7);
staticArray_Display(arr);
// Dynamic array
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
dynamicArray_insert_sortedArray(&arr2, 0);
dynamicArray_Display(arr2);
dynamicArray_insert_sortedArray(&arr2, -1);
dynamicArray_Display(arr2);
dynamicArray_insert_sortedArray(&arr2, 7);
dynamicArray_Display(arr2);
}
void reverse(void){
#if METHOD2
// Statically allocated memory
struct staticArray arr ={{1,2,3,4,5}, 20, 5};
staticArray_Display(arr);
reverse_array(arr.A, arr.length);
staticArray_Display(arr);
// Dynamic array
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
reverse_array(arr2.A, arr2.length);
dynamicArray_Display(arr2);
#else
// METHOD1
// Statically allocated memory
struct staticArray arr ={{1,2,3,4,5}, 20, 5};
staticArray_Display(arr);
reverse_array(arr.A, arr.length);
staticArray_Display(arr);
// Dynamic array
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
reverse_array(arr2.A, arr2.length);
dynamicArray_Display(arr2);
#endif
}
void rotate_array(void){
#ifdef LEFT_ROTATE
// Statically allocated array
struct staticArray arr ={{1,2,4,5,6},20, 5};
staticArray_Display(arr);
rotate_left(arr.A, arr.length);
staticArray_Display(arr);
rotate_left(arr.A, arr.length);
staticArray_Display(arr);
// Dynamically allocated array
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
rotate_left(arr2.A, arr2.length);
dynamicArray_Display(arr2);
rotate_left(arr2.A, arr2.length);
dynamicArray_Display(arr2);
#else
// Statically allocated array
struct staticArray arr ={{1,2,4,5,6},20, 5};
staticArray_Display(arr);
rotate_right(arr.A, arr.length);
staticArray_Display(arr);
rotate_right(arr.A, arr.length);
staticArray_Display(arr);
// Dynamically allocated array
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
rotate_right(arr2.A, arr2.length);
dynamicArray_Display(arr2);
rotate_right(arr2.A, arr2.length);
dynamicArray_Display(arr2);
#endif
}
void shift_array(void){
#ifdef LEFT_SHIFT
struct staticArray arr ={{1,2,4,5,6}, 20, 5};
staticArray_Display(arr);
left_shift(arr.A, arr.length);
staticArray_Display(arr);
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
left_shift(arr2.A, arr2.length);
dynamicArray_Display(arr2);
#else
struct staticArray arr ={{1,2,4,5,6}, 20, 5};
staticArray_Display(arr);
right_shift(arr.A, arr.length);
staticArray_Display(arr);
struct dynamicArray arr2 = createDynamicStruct();
dynamicArray_Display(arr2);
right_shift(arr2.A, arr2.length);
dynamicArray_Display(arr2);
#endif
}
void binary_Search(void){
struct staticArray C ={{1,3,4,5,6,8},20, 6};
struct dynamicArray D = createDynamicStruct();
printf("Index of key in array: %d\n", Recursive_BinarySearch(C.A, 1, 3, 0));
printf("Index of key in array: %d\n", Iterative_BinarySearch(C.A, C.length, 0));
printf("Index of key in array: %d\n", Recursive_BinarySearch(D.A, 0, 5, 0));
printf("Index of key in array: %d\n", Iterative_BinarySearch(D.A, D.length, 0));
}
void linear_Search(void){
// Create a static Array struct
struct staticArray A = {{1,2,3,4},20, 4};
staticArray_Display(A);
printf("Index of value found: %d\n",staticArray_linearSearch(&A, 3));
staticArray_Display(A);
printf("Index of value found: %d\n",staticArray_linearSearch(&A, 3)); // Index will be different because we moved the value to left by 1 index
staticArray_Display(A);
printf("Index of value found: %d\n",staticArray_linearSearch(&A, 3)); // Index will be different because we moved the value to left by 1 index
staticArray_Display(A);
// Create a dynamic array struct
struct dynamicArray B = createDynamicStruct();
dynamicArray_Display(B);
printf("Index of value found: %d\n", dynamicArray_linearSearch(&B, 3));
dynamicArray_Display(B);
}
void delete_at_index(void){
// Create a static Array struct
struct staticArray A = {{1,2,3,4},20, 4};
staticArray_Display(A);
printf("Deleted value is: %d\n",staticArray_deleteAtIndex(&A, -1));
staticArray_Display(A);
// Create a dynamic array struct
struct dynamicArray B = createDynamicStruct();
dynamicArray_Display(B);
printf("Deleted value is: %d\n", dynamicArray_deleteAtIndex(&B, 0));
dynamicArray_Display(B);
}
struct dynamicArray createDynamicStruct(void){
struct dynamicArray B;
printf("Size of the array?\n");
scanf("\n %d \n", &B.size);
B.A = (int *)malloc(B.size*sizeof(int)); // Allocate memory for Array
printf("\n");
printf("How many elements in the array?\n");
scanf("%d\n",&B.length);
printf("Enter values of the elements.\n");
int i;
for(i=0; i<B.length; i++){
scanf("%d", &B.A[i]);
}
return B;
}
void insert_at_index(void){
// Create a staticArray
/*struct staticArray A = {{1,4,5,6}, 20, 4};
staticArray_Display(A);
staticArray_insertAtIndex(&A,0,9);
staticArray_Display(A);
*/
// Create a dynamic struct
struct dynamicArray B = createDynamicStruct();
dynamicArray_Display(B);
dynamicArray_insertAtIndex(&B,0, 12);
dynamicArray_Display(B);
}
void dynamicArray_Display(struct dynamicArray arr){
int i;
printf("\nElements are \n");
for(i=0;i<arr.length;i++){
printf("%d ",arr.A[i]);
}
printf("\n");
}
void dynamicallyAllocatedArray(void){
struct dynamicArray arr;
printf("Enter size of an Array \n");
scanf("%d", &arr.size); // Get size of array from keyboard
arr.A = (int *) malloc(arr.size*sizeof(int)); // Allocate memory for array in heap
arr.length =0;
int n,i;
printf("Enter number of numbers. \n");
scanf("%d", &n);
// To read values from keyboard
printf("Enter all elements.\n");
for(i=0;i<n;i++){
scanf("%d", &arr.A[i]);
}
arr.length =n;
dynamicArray_Display(arr);
}
void staticArray_Display(struct staticArray arr){
int i;
printf("\nElements are \n");
for(i=0;i<arr.length;i++){
printf("%d ",arr.A[i]);
}
printf("\n");
}
void staticallyAllocatedArray(void){
struct staticArray A = { {1,2,3,5}, 10, 5}; // Declaration and initialization
staticArray_Display(A);
}
// Append value to the end of an Array
void dynamicArray_append(struct dynamicArray *arr, int value){
// Check if array full
if(arr->length == arr->size){
printf("Array is full.\n");
return;
}else{
// Append new value to the end of array
arr->A[arr->length]=value;
// Increment length
arr->length++;
}
}
// Append value to the end of an Array
void staticArray_append(struct staticArray *arr, int value){
// Check if array full
if(arr->length == arr->size){
printf("Array is full.\n");
return;
}else{
// Append new value to the end of array
arr->A[arr->length]=value;
// Increment length
arr->length++;
}
}
void append_to_array(void){
// Create an array struct
struct staticArray A ={{1,2,4,5}, 20, 4}; // declared and initialized an array struct
// Display current array elements
staticArray_Display(A);
staticArray_append(&A, 64);
staticArray_Display(A);
}
// This function has min and max time complexity
// If the new value is added to the end of the array -> no shifting required, O(1)
// If the new value is added to the front of the array -> shifting "length" elements -> loop executed O(length), or O(n) where n is size of array.
// Typical only care about worse case time of a function -> so, O(n)
void staticArray_insertAtIndex(struct staticArray *arr, int index, int value){
// First check if index in within bounds of the array
if(index>arr->size || index<0){
printf("Index out of array bounds.\n");
return;
}else{
// Starting at length, shift all the elements on left to the right,
// decrement the iterator, until iterator = index, then insert new element there
int i;
for(i=arr->length; i>index; i--){
arr->A[i]=arr->A[i-1]; // Element on left of 'i' is moved to current 'i'
}
// i == index
arr->A[i] = value;
// increase length by 1
arr->length++;
}
}
void dynamicArray_insertAtIndex(struct dynamicArray *arr, int index, int value){
// First check if index in within bounds of the array
if(index>arr->size || index<0){
printf("Index out of array bounds.\n");
return;
}else{
// Starting at length, shift all the elements on left to the right,
// decrement the iterator, until iterator = index, then insert new element there
int i;
for(i=arr->length; i>index; i--){
arr->A[i]=arr->A[i-1]; // Element on left of 'i' is moved to current 'i'
}
// i == index
arr->A[i] = value;
// increase length by 1
arr->length++;
}
}
/*
The delete function has a min and max time complexity.
If the delete element is at the end of array, then no shifting required -> O(1)
If the delet element is at the start, then shifting by "length" elements, so O(n) complexity.
*/
int staticArray_deleteAtIndex(struct staticArray *arr, int index){
// First check if index is within length of the array
if(index<0 || index>arr->length){
printf("Index is out of bound.\n");
return 0;
}else
{
// Start at delete index and shift elements from right to left until you reach lenght-1
int x = arr->A[index], i;
for(i=index; i<arr->length-1; i++){
arr->A[i] = arr->A[i+1];
}
// Update length of Array
arr->length--;
return x;
}
}
int dynamicArray_deleteAtIndex(struct dynamicArray *arr, int index){
// First check if index is within length of the array
if(index<0 || index>arr->length){
printf("Index is out of bound.\n");
return 0;
}else
{
// Start at delete index and shift elements from right to left until you reach lenght-1
int x = arr->A[index],i;
for(i=index; i<arr->length-1; i++){
arr->A[i] = arr->A[i+1];
}
// Update length of Array
arr->length--;
return x;
}
}
// Used in Improved linear search to swap a successfull search index with value at index-1 to speed up next search of the same value
void swap( int *x, int *y){
*(x)^=*(y);
*(y)^=*(x);
*(x)^=*(y);
}
/*
Linear Search requires no duplication.
An improvment to typical linear search is: if you're repeatedly searching
for the same element, you can swap that element with the element before it,
this way the element slowly moves to the front of the array, thus reducing the
number of comparisons done to find it each time -> this improvement is called "Transposition".
Another improvement to is moving the element found to the front of the array,
so that if you search it again (right after first search), you will find the element at the start so your algorithm runs at best case O(1). The drawback here is that if you search for some other element, the current element at index 0 can be pushed anywhere depending on the value you're looking for right now.
Therefore, transposition improvement is slow improvement but move to front improvement is not always improving your search time.
*/
int staticArray_linearSearch(struct staticArray *arr, int value){
int i;
for(i=0; i< arr->length; i++){
if(arr->A[i] == value){
// Value found
if(i!=0){
// move the element to the previous index
swap(&arr->A[i], &arr->A[i-1]);
}
return i; // Return current index of value found
}
}
return -1; // Element not found
}
int dynamicArray_linearSearch(struct dynamicArray *arr, int value){
int i;
for(i=0; i< arr->length; i++){
if(arr->A[i] == value){
// Value found
// move the element to the previous index
if(i!=0){
// Don't want to shift element out of bound.
swap(&arr->A[i], &arr->A[i-1]);
}
return i; // Return current index of value found
}
}
return -1; // Element not found
}
// Tail Recursion
// Can easily be converted to a while loop and it is preferred over tail recurison
/*
The binary search can also be performed using recursion.
The recursive binary search is a tail recursion (i.e. function does nothing
after returning from recursive call). A tail recursion can be converted to a
while loop implementation, which is preferred as space complexity is reduced,
(recursive calls use stack memory).
*/
int Recursive_BinarySearch(int arr[], int low, int high, int key){
// Binary search performed as long as low<=high
int mid;
if(low<=high){
mid = floor((low+high)/2);
if(arr[mid]==key){
return mid;
}else if(key<arr[mid]){
// key has to be on left side
return Recursive_BinarySearch(arr, low, mid-1, key);
}else{
// key has to be on right side
return Recursive_BinarySearch(arr, mid+1, high, key);
}
}
// At point low>high, key not found
return -1;
}
/*
Pre-requisite for Binary search: The Array has to be sorted.
Procedure:
Check if key is present at midpoint of array.
If key<midpointValue
update High index to midIndex-1
If key>midpointValue
update Low index to midIndex+1
The procedure above repeats until low>high
which means there are no more elements to check, the key is not found in the array.
*/
int Iterative_BinarySearch(int arr[], int length, int key){
int low = 0, high=length-1, midpoint=0;
while(low<=high){
midpoint = floor((low+high)/2);
if(arr[midpoint]==key){
return midpoint;
}else if(key<arr[midpoint]){
//update high because key if exists, has to be on left
high = midpoint-1;
}else{
// update low becaue key if exists, has to be on right
low = midpoint+1;
}
}
// At this point, there are no elements to check
return -1; // key not found
}
/*
You start at index 0, copy value at index 1 to index 0
Process repeated until you reach the end of array.
Element at index 0 is lost
*/
void left_shift(int *arr, int length){
int i;
for(i=0;i<length; i++){
arr[i] = arr[i+1];
}
arr[length-1] = 0;
}
/*
You start at the end of the array, copy second last to last,
process repeats until you reach the first index
Element at the end is lost
*/
void right_shift(int *arr, int length){
int i;
for(i=length-1;i>0;i--){
arr[i]=arr[i-1];
}
arr[0] = 0; // The first element is set to 0
}
/*
Rotate is similar to shift, except that the element lost is wrapped around.
For Left rotate, the element at index 0 is brought to end index
For right rotate, the element at end index is brought to index 0
*/
void rotate_left(int *arr, int length){
int i, firstElement = arr[0];
// Start at the front of the array
for(i=0;i<length;i++){
arr[i]=arr[i+1];
}
arr[length-1] = firstElement; // Bring first element to end of array
}
/*
In rotating right, the last index value is brought to the front of the array
*/
void rotate_right(int *arr, int length){
int i, lastElement = arr[length-1];
for(i=length-1;i>0;i--){
arr[i]=arr[i-1]; // Copy left index to the current index
}
arr[0] = lastElement;
}
/*
Reversing can be done in two ways:
1) Create another array of same size and use two iterators,
one pointing to end of original and the other pointing to start
of new array. Copy elements over.
After copy elements in reverse to the new array, copy the new array to old array and return new array memory to program
2) Use two iterators, one pointing to front and the other to the end
Swap the values at these indices, increment front iterator and decrement end iterator. This is repeated until the two iterators are equal or if front iterator is > end iterator
*/
void reverse_array(int *arr, int length){
#ifdef METHOD2
// Method 2 is simpler, because its a single for loop
int i, j,temp;
for(i=0, j=length-1;i<j;i++, j--){
// swap the two values
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
#else
// Method 1
int *tempArr = (int *)malloc(length*sizeof(int));
// Copy elements from arr into tempArr in reverse
int i, j;
for(i=length-1,j=0;i>=0;i--,j++){
tempArr[j]=arr[i];
}
// Copy values in tempArr over to original arr
for(i=0;i<length;i++){
arr[i] = tempArr[i];
}
// release dynamically allocated memory for tempArr
free(tempArr);
#endif
}
/*
Insert a value in a sorted array.
The idea is to start at the end of the array and if the given value is
less than current index value, shift the value to the right. You repeat this
until you reach an element in the array whose value is less than given value.
The typical way done is you look for position in the sorted array and then shift all the elements after that to the right to make room. But, its better to start at the end of the sorted array and shift while you look for its correct position of insertion.
*/
void staticArray_insert_sortedArray(struct staticArray *arr, int value){
if(arr->length==arr->size){
// No room for insertion
printf("Array is full.\n");
return;
}else if(arr->length<arr->size){
// There is room for insertion
int i = (arr->length)-1; // Start at the end of the sorted array
// Keep shifting elements to the right if the current element is > value
// I'm assuming the list is sorted in ascending order
// The (i!=-1) is added for case when given value has to be inserted at the
// front -> worse case scenario of this algorithm
while(arr->A[i]>value && (i!=-1)){
arr->A[i+1] = arr->A[i]; // shifting element to the right
i--;
}
// arr[i] < value, therefore, 'value' is inserted right after
arr->A[i+1] = value;
(arr->length)++; // Increase length, new element added.
}
}
void dynamicArray_insert_sortedArray(struct dynamicArray *arr, int value){
if(arr->length==arr->size){
// No room for insertion
printf("Array is full.\n");
return;
}else if(arr->length<arr->size){
// There is room for insertion
int i = (arr->length)-1; // Start at the end of the sorted array
// Keep shifting elements to the right if the current element is > value
// I'm assuming the list is sorted in ascending order
// The (i!=-1) is added for case when given value has to be inserted at the
// front -> worse case scenario of this algorithm
while(arr->A[i]>value && (i!=-1)){
arr->A[i+1] = arr->A[i]; // shifting element to the right
i--;
}
// arr[i] < value, therefore, 'value' is inserted right after
arr->A[i+1] = value;
(arr->length)++; // Increase length, new element added.
}
}
/*
You compare pair of indices starting at front and you look for first pair that
is not sorted. i.e. if checking for sorted in ascending order,
then element at i should be less than element at i+1, find first pair that negates this and return false
Key note: You don't traverse the array till length-1, because you can't
compare element at length-1 with non-exisiting element at length,
so, you stop at length-1 for last pair comparison.
*/
bool isSorted(int arr[], int length){
int i;
for(i=0;i<length-1;i++){
if(arr[i]>arr[i+1]){
// found a pair not in ascending order
return false;
}
}
// You reached here, that means the list is sorted in ascending order
return true;
}
/*
This function moves all the negative numbers in an array to the left
and all the positive numbers to the right.
The idea is to use two iterators, one starting at the front and one at the back.
The front iterator will look for positive numbers and the back iterator will
look for negative numbers. When they've found their numbers, the two will swap to push positive to the front and the negative to the end. This is repeated until the front iterator cross the back iterator, which means you've pushed all the negative to the front and all the positive numbers to the right.
This algorithm does n+2 comparisons -> time complexity is o(n)
*/
void move_negative_to_left(int *arr, int length){
int i = 0, j=length-1;
while(i<j){
// The two iterators keep moving until i crosses j,
// then you scanned full array
while(arr[i]<0){
// Its negative number, move to next index
i++;
} // end of this while -> you've found a positive number
while(arr[j]>0){
// Its a positive number, move to previous index
j--;
}// end of this while -> you've found a negative number
if(i<j){
// Swap the two numbers iff i hasn't crossed j
swap(&arr[i], &arr[j]);
}
}
}