C++ STL के इस Hindi Tutorial में हम List के बारे में बात करेंगे और सबसे पहले ये समझेंगे की List और Vector में क्या difference हैं और फिर इसके बाद हम STL List को और उसके functions को कैसे use करते हैं ये सीखेंगे.
C++ STL List भी Vector की तरह sequence containers है लेकिन इनमें फर्क ये होता है की Vector में elements contiguous memory में store किए जाते हैं और List में elements non contiguous memory में store किए जाते हैं.
STL List को internally doubly linked list के तौर पर implement किया जाता है इसलिए List में elements को randomly access नहीं किया जा सकता और हमें एक-एक करके सभी elements पर iterate करते हुए किसी specific element को access करना होता है.
जब आप Vector में elements को insert और delete करते हो तो internally shifting और copy operation में बहुत ज्यादा processing होती है लेकिन List में internally कुछ pointers आपस में address change करके बहुत ही कम processing में elements को insert और delete कर देते हैं.
अब क्योंकि STL List में random access का support नहीं होता इसलिए वो STL algorithms (functions) जो किसी task को perform करने के लिए random access iterators का use करते हैं उन्हें हम List के साथ use नहीं कर सकते.
लेकिन इसी वजह से List container में आपको sorting, splicing, removing और कुछ अन्य operations के लिए extra methods मिलते हैं.
C++ STL List Declaration
अपने C++ programs में List को use करने के लिए सबसे पहले हमें list header file को अपने program में include करना होता है.
#include <list>
Header file include करने के बाद आप list को declare कर सकते हो और क्योंकि STL में सभी containers templates के तौर पर use होते हैं इसलिए list declare करते वक्त आपको उसका type parameter बताना होगा.
list<T> list_name;
आप list declare करते वक्त type parameter में जो data type specify करोगे सिर्फ उसी type का data आप list container में store कर सकते हो.
list<int> mylist1;
list<char> mylist2;
list<string> mylist3;
C++ STL List Initialization
List container में data store करने के दो तरीके होते हैं एक आप खुद list declaration के वक्त ही उसे initialize कर सकते हो और दूसरा प्रोग्राम run होते वक्त user से कीबोर्ड के जरिये list में इनपुट ले सकते हो.
अभी हम ये देखने वाले हैं की आप खुद से कैसे और कितने तरीकों से list initialization कर सकते हो. मैंने नीचे सभी syntax को explain किया हुआ है.
// First Way Empty List
list<int> mylist;
// Second Way: Initializer list
list<int> mylist1 = {1, 2, 3, 4, 5};
// Third Way: Uniform initialization
list<int> mylist2 {1, 2, 3, 4, 5};
// Fourth Way: Size, Value Fill
list<int> mylist3(4, 7);
// Fifth Way: Size with 0 values
list<int> mylist4(5);
// Sixth Way:
list<data_type> lname(beginIt, endIt);
Fourth way में हमने 4 size का एक List declare की है जिसकी सभी चारो values 7 होगी. Fifth way में हमने 5 size का List declare किया है जिसकी सभी पाँचों values 0 होगी और sixth way में आप another container के elements को अपनी list में initialize कर सकते हो.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist = {10,20,30,40,50};
cout<<"Print List Elements using Range Based Loop:-"<<endl;
for(auto ele : mylist)
{
cout<<ele<<" ";
}
cout<<"\nPrint List Elements using Iterator:-"<<endl;
for(auto it = mylist.begin(); it != mylist.end(); it++)
{
cout<<*it<<" ";
}
return 0;
}
Output:
Print List Elements using Range Based Loop:-
10 20 30 40 50
Print List Elements using Iterator:-
10 20 30 40 50
C++ STL List Functions
List container class में बहुत सारे member functions होते हैं जिसकी लिस्ट नीचे दी है इन सभी functions को हम एक-एक करके use करना सीखेंगे.
begin() | end() |
rbegin() | rend() |
size() | resize() |
empty() | – |
front() | back() |
push_back() | pop_back() |
push_front() | pop_front() |
insert() | assign() |
erase() | clear() |
remove() | remove_if() |
swap() | reverse() |
merge() | splice() |
sort() | unique() |
begin() function
ये function list container के first element के address को return करता है जिसे आप किसी iterator में store कर सकते हो.
end() function
ये function list container के last element के बाद वाले address को return करता है जिसे आप किसी iterator में store कर सकते हो.
rbegin() function
ये function list container के last element के address को return करता है जिसे आप किसी iterator में store कर सकते हो और फिर आप चाहो तो आप इस iterator से reverse order में traverse कर सकते हो.
rend() function
ये function list container के first element से पहले वाले address को return करता है जिसे आप किसी iterator में store कर सकते हो.
Example Program:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
int main()
{
list<string> names = {"Karan","Rohit","Sanjay","Deepak"};
cout<<"Print List Element in Forward Order:-"<<endl;
for(auto it = names.begin(); it != names.end(); it++)
{
cout<<*it<<" ";
}
cout<<"\nPrint List Element in Reverse Order:-"<<endl;
for(auto it = names.rbegin(); it != names.rend(); it++)
{
cout<<*it<<" ";
}
return 0;
}
Output:
Print List Element in Forward Order:-
Karan Rohit Sanjay Deepak
Print List Element in Reverse Order:-
Deepak Sanjay Rohit Karan
size() function
ये function एक number return करता है जो की ये बताता है की List में कितने elements store हैं.
resize(size) / resize(size,ele) function
इस function की help से आप List को resize कर सकते हो. अगर आप इस function के argument में current size से कम size pass कर सकते हो तो ये function पास किये गये size के बाद वाले elements को remove कर देता है.
अगर आप इस function के argument में current size से ज्यादा size pass करते हो तो ये function पास किये गये size के बाद 0 value की copies या second argument में बताये गये element की copies से fill करके resize कर देगा.
empty() function
अगर आपकी List खाली है यानी उसमें कोई भी element store नही है तो ये function 1 (true) return करेगा और अगर List में एक भी element है तो ये function 0 (false) return करेगा.
Example Program:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
int main()
{
list<string> mylist = {"Karan","Rohit","Sanjay","Deepak"};
cout<<"List Size: "<<mylist.size();
mylist.resize(5);
cout<<"\nList Elements After Resize:-"<<endl;
for(auto it = mylist.begin(); it != mylist.end(); it++)
{
cout<<*it<<" ";
}
mylist.resize(8,"HMT");
cout<<"\nList Elements After Resize:-"<<endl;
for(auto it = mylist.begin(); it != mylist.end(); it++)
{
cout<<*it<<" ";
}
if(mylist.empty())
cout<<"\nList is Empty"<<endl;
else
cout<<"\nList is Not Empty"<<endl;
return 0;
}
Output:
List Size: 4
List Elements After Resize:-
Karan Rohit Sanjay Deepak
List Elements After Resize:-
Karan Rohit Sanjay Deepak HMT HMT HMT
List is Not Empty
front() function
ये function List container का first element return करता है.
back() function
ये function List container का last element return करता है.
Example Program:
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<string> mylist = {"Karan","Rohit","Sanjay","Deepak"};
cout<<"First Element: "<<mylist.front()<<endl;
cout<<"Last Element: "<<mylist.back()<<endl;
return 0;
}
Output:
First Element: Karan
Last Element: Deepak
void push_back(ele) function
इस function की help से आप List के last (end) में element add (insert) कर सकते हो.
void pop_back() function
इस function की help से आप List के last (end) से element remove (delete) कर सकते हो.
void push_front(ele) function
इस function की help से आप List के starting में element add (insert) कर सकते हो.
void pop_front() function
इस function की help से आप List के starting से element remove (delete) कर सकते हो.
Example Program:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
int main()
{
list<string> mylist;
mylist.push_back("Karan");
mylist.push_back("Sanjay");
mylist.push_back("Rohit");
mylist.push_front("Deepak");
for(auto ele : mylist)
{
cout<<ele<<" ";
}
cout<<endl;
mylist.pop_back();
mylist.pop_front();
for(auto ele : mylist)
{
cout<<ele<<" ";
}
return 0;
}
Output:
Deepak Karan Sanjay Rohit
Karan Sanjay
Explanation:
ऊपर program में हमने सबसे पहले एक list को string data type के साथ declare किया है. इसके बाद push_back() function की हेल्प से 3 names को एक के पीछे एक add किया है. इसके बाद push_front() function की help से 1 name को List के आगे add किया है. इसके बाद range based for loop की हेल्प से अपनी List को print कराया है.
इसी तरह pop_back() की हेल्प से list के last से और pop_front() की हेल्प से list के front से एक-एक element को remove किया है और फिर से list को print कराया है.
List insert() functions
List में insert() function 3 तरह overload है यानी इसे हम 3 तरीकों से call कर सकते हैं और हर तरीके में ये function अलग तरह से काम करता है.
insert(iterator, element) function
जब आपको List में single element किसी भी position पर insert करना हो तब हम इस function को use करते हैं.
आप जिस List container के object से इस function को call करोगे उसी List container का iterator आपको इस function में first argument के तौर पर pass करना होगा.
इस function के second parameter में आप जो element (value) आप pass करोगे वो element उस iterator वाली position से just पहले add हो जायेगा.
insert(iterator, times, element) function
जब आपको List में single element किसी भी position पर एक से ज्यादा times copies (insert) करना हो तब हम इस function को use करते हैं.
आप जिस List container के object से इस function को call करोगे उसी List container का iterator आपको इस function में first argument के तौर पर pass करना होगा.
इस function के second function में आप जो number पास करोगे उतनी बार (times), third parameter में पास की गया element उस iterator वाली position पर insert (copy) हो जायेगा.
insert(iterator, start_iterator, end_iterator) function
इस function की help से आप एक List में किसी दुसरे container के elements copy (insert) कर सकते हो.
आप जिस List container के object से इस function को call करोगे उसी List container का iterator आपको इस function में first argument के तौर पर pass करना होगा. इसी iterator position से पहले सभी elements copy होंगे.
आप जिस दुसरे container से elements copy करना चाहते हो उस container से copy करने वाले से elements का starting iterator और ending iterator को आपको इस function के second और third arguments के तौर पर pass करना होगा.
Return Value: ऊपर के दोनों insert() functions कुछ भी return नहीं करते लेकिन ये insert() function एक iterator return करता है जिसके पास newly inserted elements का starting address होगा.
Example Program:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
int main()
{
list<int> mylist1 = {25,35,45,55,65};
list<int> mylist2 = {10,20,30};
auto it1 = mylist1.begin();
mylist1.insert(it1,75);
for(int ele : mylist1)
cout<<ele<<" ";
cout<<endl;
auto it2 = mylist1.begin();
advance(it2,3);
mylist1.insert(it2,85);
for(int ele : mylist1)
cout<<ele<<" ";
cout<<endl;
mylist1.insert(it2,3,90);
for(int ele : mylist1)
cout<<ele<<" ";
cout<<endl;
auto itx = mylist2.begin();
auto ity = mylist2.end();
mylist1.insert(it2,itx,ity);
for(int ele : mylist1)
cout<<ele<<" ";
return 0;
}
Output:
75 25 35 45 55 65
75 25 35 85 45 55 65
75 25 35 85 90 90 90 45 55 65
75 25 35 85 90 90 90 10 20 30 45 55 65
erase(iterator) function
आप जिस List container के object से इस function को call करोगे उसी List container का iterator आपको इस function में argument के तौर पर pass करना होगा और फिर ये function उस element को remove कर देगा जिसका address pass किये गये iterator पर होगा.
erase(start_iterator, end_iterator) function
आप जिस List container के object से इस function को call करोगे उसी List container की range के 2 iterators आपको इस function में arguments के तौर पर pass करना होगा और फिर ये function उस range के elements को remove कर देगा जिस range के iterator आपने function में pass किये हैं
नोट: Second iterator का element erase नहीं होता क्योंकि वो range में exclusive होता है.
Return value: ये दोनों functions erase किये गये elements के बाद वाले element का iterator return करते हैं.
clear() function
ये function List container के सभी elements को remove कर देगा.
Example Program:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
int main()
{
list<int> mylist = {10,25,30,35,40,45,55,60,65};
auto it = mylist.begin();
//remove first element
mylist.erase(it);
//display list elements
for(int ele : mylist)
cout<<ele<<" ";
cout<<endl;
auto it1 = mylist.begin();
//iterator position on 35
advance(it1,2);
auto it2 = mylist.begin();
//iterator position on 60
advance(it2,6);
//remove elements between range
mylist.erase(it1,it2);
//display list elements
for(int ele : mylist)
cout<<ele<<" ";
//remove all elements
mylist.clear();
cout<<"\nList Size: "<<mylist.size();
return 0;
}
Output:
25 30 35 40 45 55 60 65
25 30 60 65
List Size: 0
assign(times, value) function
इस function की help से आप किसी List को कोई एक element (value) multiple times assign (copy) कर सकते हो और अगर उस List में कोई elements पहले से हुए तो वो remove हो जायेंगे और List resize हो जायेगा.
assign(start_iterator, end_iterator) function
इस function की help से आप किसी एक List में किसी दुसरे List के elements को assign (copy) कर सकते हो और जिस List में element copy किए उसमें अगर पहले कोई elements हुए तो वो remove हो जायेंगे और List resize हो जायेगा.
reverse() function
इस function की हेल्प से हम List के elements को internally (in-place) reverse कर सकते हैं.
swap(List2) function
इस function की help से आप 2 Lists के elements को आपस में बदल (swap) सकते हो.
Example Program:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
int main()
{
list<int> mylist1 = {25,35,45,55,65};
list<int> mylist2 = {10,20,30};
list<int> mylist3 = {2,4,5,8};
mylist1.assign(3,6);
for(int ele : mylist1)
cout<<ele<<" ";
cout<<endl;
auto it1 = mylist2.begin();
auto it2 = mylist2.end();
mylist1.assign(it1,it2);
for(int ele : mylist1)
cout<<ele<<" ";
cout<<endl;
mylist1.swap(mylist3);
for(int ele : mylist1)
cout<<ele<<" ";
cout<<endl;
mylist1.reverse();
for(int ele : mylist1)
cout<<ele<<" ";
return 0;
}
Output:
6 6 6
10 20 30
2 4 5 8
8 5 4 2
remove(value) function
इस function को call करते वक्त हम जो value argument के तौर पर pass करते हैं वो value अगर list में मौजूद है तो ये function उस value को list में सभी जगहों पर से remove कर देगा.
remove_if(functionName) function
इस function को call करते वक्त हम एक predicate function को argument के तौर पर pass करते हैं फिर ये function internally उस predicate function को call करता है और list के सभी elements को एक-एक करके argument के तौर पर pass करता है और जिस-जिस element के लिए predicate function true return करता है ये function को उस-उस elements को list में से remove कर देता है.
C++ में predicate function ऐसे functions को कहा जाता है जिन्हें call करते वक्त एक या एक ज्यादा arguments pass किए जाते हैं और वो functions किसी तरह की conditional processing करने के बाद एक boolean value (true, false) return करते हैं.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
bool isEven(int ele)
{
if(ele%2==0)
return true;
else
return false;
}
int main()
{
list<int> mylist = {15,40,26,38,40,17,40,60,33};
mylist.remove(40);
for(auto ele : mylist)
{
cout<<ele<<" ";
}
cout<<endl;
mylist.remove_if(isEven);
for(auto ele : mylist)
{
cout<<ele<<" ";
}
return 0;
}
Output:
15 26 38 17 60 33
15 17 33
sort() function
इस function की हेल्प से हम अपनी list elements को ascending order में sort कर सकते हैं.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist = {50,20,30,40,10};
cout<<"Before Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.sort();
cout<<"\n\nAfter Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
return 0;
}
Output:
Before Sorting:-
50 20 30 40 10
After Sorting:-
10 20 30 40 50
sort( functionName ) function
मान लीजिये आपके पास string type की एक list है और आप उसके elements को dictionary (lexicographical) order के basis पर नही बल्कि string की length के basis पर sort करना चाहते हो या मैं कहूँ की आप अपनी list element को अपने किसी custom logic के आधार पर sort करना चाहते हो तब हम इस function का use करते हैं.
इस function को call करते वक्त हम एक comparator function को argument के तौर पर pass करते हैं फिर ये function internally उस comparator function को multiple times call करता है.
जब इस comparator function को call किया जाता है तो list की 2 values को इसमें pass किया जाता है और फिर उन दोनों values को आपस में compare किया जाता है और फिर return value (true या false) के basis पर elements को sort किया जाता है.
जब comparator function में first argument को second argument से less than ( a < b ) के आधार पर compare करते हो तब आपकी list को ascending order में sort किया जाता है और जब first argument को second argument से greater than ( a > b ) के आधार पर compare करते हो तब आपकी list को descending order में sort किया जाता है.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
bool checkLength(string str1,string str2)
{
return str1.length() < str2.length();
}
int main()
{
list<string> mylist = {"Bhupendra","Zenith","Anu","Jatin","Yogi","Niketan"};
cout<<"Before Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.sort();
cout<<"\n\nAfter Simple Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.sort(checkLength);
cout<<"\n\nAfter Custom Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
return 0;
}
Output:
Before Sorting:-
Bhupendra Zenith Anu Jatin Yogi Niketan
After Simple Sorting:-
Anu Bhupendra Jatin Niketan Yogi Zenith
After Custom Sorting:-
Anu Yogi Jatin Zenith Niketan Bhupendra
unique( ) function
जब हम sort function की हेल्प से किसी list को sort करते हैं तो अगर उस list में कोई element अगर एक से ज्यादा बार है तो वो elements sorted list में consecutive (लगातार) store होते हैं और अब आप इन duplicate consecutive elements को remove करना चाहते हो तो इसके लिए हम unique function को use करते हैं.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist = {50,20,30,40,10,20,30,60,10};
cout<<"Before Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.sort();
cout<<"\n\nAfter Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.unique();
cout<<"\n\nAfter Remove Duplicate Elements:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
return 0;
}
Output:
Before Sorting:-
50 20 30 40 10 20 30 60 10
After Sorting:-
10 10 20 20 30 30 40 50 60
After Remove Duplicate Elements:-
10 20 30 40 50 60
unique( functionName ) function
जब हम किसी Sorted list के consecutive elements को delete करने के लिए अपना custom logic add करना चाहते हैं जैसे हमने ऊपर sort() और remove_if() function में किया था तब हम unique() function में अपना binary predicate function pass करते हैं और इसी predicate function की return value (true या false) के basis पर consecutive elements को delete किया जाता है.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
bool myCompare(float a,float b)
{
return ((int)a == (int)b);
}
int main()
{
list<double> mylist = {4.5,2.3,6.7,2.8,6.3,4.1,1.5,5.4};
cout<<"Before Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.sort();
cout<<"\n\nAfter Sorting:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.unique();
cout<<"\n\nAfter Simple Unique Function:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
mylist.unique(myCompare);
cout<<"\n\nAfter Predicate Unique Function:-\n";
for(auto ele : mylist)
{
cout<<ele<<" ";
}
return 0;
}
Output:
Before Sorting:-
4.5 2.3 6.7 2.8 6.3 4.1 1.5 5.4
After Sorting:-
1.5 2.3 2.8 4.1 4.5 5.4 6.3 6.7
After Simple Unique Function:-
1.5 2.3 2.8 4.1 4.5 5.4 6.3 6.7
After Predicate Unique Function:-
1.5 2.3 4.1 5.4 6.3
splice(list1_iterator, list2) function
इस function की हेल्प से आप एक list के सभी elements को दूसरी list में किसी specific position पर transfer (move) कर सकते हो.
जिस list के जरिये आप इस function को call करेंगे उसका size increase हो जायेगा और जिस list को आप इस function में arguments के तौर पर pass करेंगे वो list empty हो जाएगी और उसका size 0 हो जायेगा.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist1 = {23,56,40,78};
list<int> mylist2 = {10,20,30,40};
auto it = mylist1.begin();
mylist1.splice(it,mylist2);
cout<<"List 1 Elements:-"<<endl;
for(auto ele : mylist1)
{
cout<<ele<<" ";
}
cout<<"\nList 2 Size: "<<mylist2.size()<<endl;
return 0;
}
Output:
List 1 Elements:-
10 20 30 40 23 56 40 78
List 2 Size: 0
splice(list1_iterator, list2, list2_iterator) function
इस function की हेल्प से आप एक list के किसी specific position पर मौजूद किसी single element को दूसरी list में किसी specific position पर transfer (move) कर सकते हो. जो element एक list में से दूसरी list move होगा वो अपनी list में से remove हो जायेगा.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist1 = {23,56,40,78};
list<int> mylist2 = {10,20,30,40,50};
auto it1 = mylist1.end();
auto it2 = mylist2.begin();
mylist1.splice(it1,mylist2,it2);
cout<<"List 1 Elements:-"<<endl;
for(auto ele : mylist1)
{
cout<<ele<<" ";
}
cout<<"\nList 2 Elements:-"<<endl;
for(auto ele : mylist2)
{
cout<<ele<<" ";
}
return 0;
}
Output:
List 1 Elements:-
23 56 40 78 10
List 2 Elements:-
20 30 40 50
splice(list1_it, list2, list2_itX, list2_itY) function
इस function की हेल्प से आप एक list के किसी range के elements को किसी दूसरी list में किसी specific position पर transfer (move) कर सकते हो. जो elements एक list में से दूसरी list move होंगे वो अपनी list में से remove हो जायेंगे.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist1 = {23,56,40,78};
list<int> mylist2 = {10,20,30,40,50};
auto it1 = mylist1.end();
auto itx = mylist2.begin();
auto ity = mylist2.begin();
advance(ity,3);
mylist1.splice(it1,mylist2,itx,ity);
cout<<"List 1 Elements:-"<<endl;
for(auto ele : mylist1)
{
cout<<ele<<" ";
}
cout<<"\nList 2 Elements:-"<<endl;
for(auto ele : mylist2)
{
cout<<ele<<" ";
}
return 0;
}
Output:
List 1 Elements:-
23 56 40 78 10 20 30
List 2 Elements:-
40 50
list1.merge(list2) function
इस function की हेल्प से आप दो sorted lists को आपस में merge करके एक sorted list बना सकते हो.
Example Program:
#include<iostream>
#include<list>
#include<iterator>
using namespace std;
int main()
{
list<int> mylist1 = {15,25,35};
list<int> mylist2 = {10,20,30,40};
mylist1.merge(mylist2);
cout<<"List Elements:"<<endl;
for(auto ele : mylist1)
{
cout<<ele<<" ";
}
return 0;
}
Output:
List Elements:
10 15 20 25 30 35 40