Skip to content

Commit 155f545

Browse files
authored
Merge pull request #36 from yusuf601/main
implement two new overloads for forward_list
2 parents 4ba34f5 + 951cde8 commit 155f545

File tree

3 files changed

+137
-16
lines changed

3 files changed

+137
-16
lines changed

header/forward_list.hpp

Lines changed: 109 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,37 @@ class forward_lists{
156156
private:
157157
Node* node;
158158
public:
159-
Iterator(Node* n){
160-
this->node = n;
161-
}
159+
/**
160+
* @brief iterator category
161+
* iterator category adalah label yang menjelaskan kemampuan
162+
* sebuah
163+
*
164+
* @details Iterator traits
165+
* - iterator_category
166+
* traits ini adalah menandakan kemampuan sebuah iterator pada
167+
* forward_list kita memakai forward_iterator dikarenakan singly
168+
* linked list hanya punya pointer next yang memunkinkan node hanya
169+
* bisa bergerak maju
170+
* - value_type
171+
* traits ini adalah type data yg digunakan oleh forward_list
172+
* karena sudah ada Template,maka kita dapat langsung memakai Templates
173+
* tersebut
174+
* - difference_type
175+
* tipe integer untuk menyatakan selisih dua iterator,ini dipakai
176+
* pada std::distance untuk menghitung banyak node diantara 2 iterator
177+
* - using pointer = T*;
178+
* tipe pointer ke elemen yang ditunjuk iterator
179+
* - using reference = T&;
180+
* tipe referensi ke elemen,Memungkinkan penggunaan *it untuk mengakses elemen.
181+
*/
182+
using iterator_category = std::forward_iterator_tag;
183+
using value_type = T;
184+
using difference_type = std::ptrdiff_t;
185+
using pointer = T*;
186+
using reference = T&;
187+
Iterator(Node* n){
188+
this->node = n;
189+
}
162190
friend std::ostream& operator<<(std::ostream& os,const Iterator& it){
163191
if(it.node){
164192
os << it.node->data;
@@ -170,6 +198,12 @@ class forward_lists{
170198
T& operator*(){
171199
return node->data;
172200
}
201+
reference operator*()const{
202+
return node->data;
203+
}
204+
pointer operator->()const{
205+
return &(node->data);
206+
}
173207
Iterator& operator++(){ //harus mengembalikan reference ke object saat ini
174208
if(node) node = node->next;
175209
return *this;
@@ -588,7 +622,15 @@ class forward_lists{
588622
* method untuk memindahkan node dari satu list ke list lain
589623
* tanpa menyalin data,tetapi move node pointer
590624
*
591-
* @details Time complexity O(1),Space Complexity O(1)
625+
* @details Time complexity overloads
626+
* - void splice_after( const_iterator pos, forward_list& other ) -> O(1)
627+
* - void splice_after( const_iterator pos, forward_list&& other ) -> O(1)
628+
* - void splice_after( const_iterator pos, forward_list& other,
629+
const_iterator it ) -> O(1)
630+
* - void splice_after( const_iterator pos, forward_list&& other,
631+
const_iterator it ) ->O(1)
632+
* - void splice_after( const_iterator pos, forward_list& other,
633+
const_iterator first, const_iterator last ) -> O(n)
592634
*/
593635
void splice_after(const Iterator pos,forward_lists& others,const Iterator It){
594636
Node* src = It.get_raw();
@@ -640,7 +682,6 @@ class forward_lists{
640682
Node* src = pos.get_raw();//pos object saat ini
641683
Node* begin = others.head->next ; //begin object lain
642684
Node* end = others.tail; //end object lain
643-
644685
end->next = src->next;
645686
src->next = begin;
646687
//update tail
@@ -655,23 +696,75 @@ class forward_lists{
655696
others.size = 0;
656697
}
657698
void splice_after(const Iterator pos,forward_lists& others,const Iterator first,const Iterator last){
699+
//relingking dari range (first,last)
658700
Node* curr = pos.get_raw();
659-
Node* start = others.head->next;
660701
Node* other_begin = first.get_raw()->next;
661702
Node* other_end = last.get_raw();
662-
//linking other_end to curr->next
663-
other_end->next =curr->next;
664-
//lingking curr->next with to others_begin
703+
Node* after_node = curr->next; //simpan first this
704+
if(other_begin == other_end){
705+
return; //nullptr
706+
}
707+
//update size,update size sebelum di linking
708+
auto moved = (std::distance(first, last)) - 1;
709+
size += moved;
710+
others.size -= moved;
711+
//simpan last_node
712+
Node* last_node = other_begin;
713+
//cari node sebelum lasr
714+
while(last_node->next != other_end){
715+
last_node = last_node->next;
716+
//loop sampai last_node tepat menunjuk sebelum pos last
717+
}
718+
//sembungkan ke list tujuan
719+
last_node->next = curr->next;
665720
curr->next = other_begin;
721+
//lingking curr->next with to others_begin
666722

667-
//update size
668-
//karena linking dimulai dari node setelah posisi first
669-
size += std::distance(next(first,last));
670-
others.size -= size;
723+
//update tail
724+
if(after_node == tail || other_end == nullptr){
725+
tail = last_node;
726+
}
727+
//relingking object lain
728+
first.get_raw()->next = other_end;
729+
if(other_end == nullptr){
730+
others.tail = first.get_raw();
731+
}
671732

672-
//kosongkan object lain
673-
674-
tail = first.get_raw();
733+
}
734+
void splice_after(const Iterator pos,forward_lists&& others,const Iterator first,const Iterator last){
735+
//relingking dari range (first,last)
736+
Node* curr = pos.get_raw();
737+
Node* other_begin = first.get_raw()->next;
738+
Node* other_end = last.get_raw();
739+
Node* after_node = curr->next;
740+
if(other_begin == other_end){
741+
return; //nullptr
742+
}
743+
//update size,update size sebelum di linking
744+
auto moved = std::distance(std::next(first),(last));
745+
size += moved;
746+
Node* last_node = other_begin;
747+
others.size -= moved;
748+
//cari node sebelum lasr
749+
while(last_node->next != other_end){
750+
last_node = last_node->next;
751+
//loop sampai last_node tepat menunjuk sebelum pos last
752+
}
753+
//sembungkan ke list tujuan
754+
last_node->next = curr->next;
755+
curr->next = other_begin;
756+
//lingking curr->next with to others_begin
757+
758+
//update tail
759+
Node* new_begin = first.get_raw();
760+
if(after_node == tail){
761+
tail = last_node;
762+
}
763+
//relingking object lain
764+
first.get_raw()->next = other_end;
765+
if(other_end == nullptr){
766+
others.tail = first.get_raw();
767+
}
675768

676769
}
677770
public:

implementation/implementation.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <iostream>
22
#include <vector>
3+
#include <iterator>
34
#include "../header/forward_list.hpp"
45
int main(){
56
std::cout << "Pop Front" << std::endl;
@@ -84,5 +85,17 @@ int main(){
8485
// list.print_all(list.begin(),list.end());
8586
list.assign({1,2,3,4,5});
8687
list.print_all(list.begin(),list.end());
88+
forward_lists<int> a = {1, 2, 3};
89+
forward_lists<int> b = {100, 200, 300, 400, 500};
90+
91+
// pindahkan elemen (200,300,400) dari b ke setelah a.before_begin()
92+
//auto it1 = b.begin(); // menunjuk 100
93+
//auto it2 = (b.begin(), 4); // menunjuk 500
94+
95+
a.splice_after(a.before_begin(), b, b.begin(), b.end());
96+
97+
for (int x : a) std::cout << x << " "; // 200 300 400 1 2 3
98+
std::cout << "\n";
99+
for (int x : b) std::cout << x << " "; // 100 500
87100
return 0;
88101
}

test/testing.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,19 @@ TEST(splice_test,splice_testII){
241241
EXPECT_EQ(fl.get_size(),4);
242242
EXPECT_EQ(lists.get_size(),2);
243243
EXPECT_EQ(actual,expectations);
244+
}
245+
TEST(splice_test,splice_testIII){
246+
forward_lists<int>fl = {1000,2000,3000,4000,5000,6000};
247+
forward_lists<int>lists = {1,2,3,4,5};
248+
EXPECT_EQ(fl.get_size(),6);
249+
EXPECT_EQ(lists.get_size(),5);
250+
fl.splice_after(fl.begin(),lists,lists.begin(),lists.end());
251+
std::vector<int>expectations = {1000,2,3,4,5,2000,3000,4000,5000,6000};
252+
std::vector<int>actual;
253+
for(auto x: fl){
254+
actual.push_back(x);
255+
}
256+
EXPECT_EQ(fl.get_size(),10);
257+
EXPECT_EQ(lists.get_size(),1);
258+
EXPECT_EQ(actual,expectations);
244259
}

0 commit comments

Comments
 (0)