Berbagi teknologi

[C Elementary] Pemahaman awal tentang kelas daftar

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Perpustakaan standardaftarbaik

Lapisan bawah daftar adalah struktur daftar tertaut melingkar dua arah dengan bit penjaga.
Dibandingkan dengan struktur daftar tertaut tunggal forward_list, iterator daftar adalah iterator dua arah
Dibandingkan dengan wadah terstruktur berurutan seperti vektor, daftar lebih efisien dalam menyisipkan dan menghapus di posisi mana pun, tetapi tidak mendukung akses acak di posisi mana pun.
Daftar adalah kelas templat. Saat menggunakannya, kita perlu memberikan tipe elemennya.

Saat menggunakan kelas daftar, Anda perlu menyertakan file header<list>

2. Antarmuka umum kelas daftar

1. Konstruktor yang umum digunakan

1. Konstruktor default, membuat daftar tertaut kosong

list();

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. }

2. Buatlah objek daftar dan inisialisasi dengan n vals

list(size_type n, const value_type& val =  value_type());

Misalnya:

  1. void test()
  2. {
  3. list<int> lt(3, 1);
  4. for (auto i : lt)
  5. {
  6. cout << i << " ";
  7. }
  8. }

hasil operasi:

3.Salin konstruktor kelas daftar

list(const list& x); 

Misalnya:

  1. void test()
  2. {
  3. list<int> lt(3, 1);
  4. list<int> lt1(lt);
  5. for (auto i : lt1)
  6. {
  7. cout << i << " ";
  8. }
  9. }

hasil operasi:

4. Gunakan konstruktor inisialisasi iterator

  1. Template<class InputIterator>
  2. list(InputIterator first, InputIterator last);

Misalnya:

  1. void test()
  2. {
  3. list<int> lt(3, 1);
  4. list<int> lt1(lt.begin(), lt.end());
  5. for (auto i : lt1)
  6. {
  7. cout << i << " ";
  8. }
  9. }

hasil operasi:

2. Antarmuka kapasitas yang umum digunakan

Masih sama, mari saya bahas bersama-sama di sini.

1.ukuran,kosong,ukuran_maks,ubah_ukuran

ukuran:kembalidaftar tertautJumlah elemen dalam wadah.

size_type size() const;

kosong:kembalidaftarApakah wadahnya kosong (yaituukuranadalah 0).
(Catatan: Fungsi ini tidak mengubah wadah dengan cara apa pun. Untuk menghapusdaftar tertautIsi wadahnya, lihatdaftar::bersih。)

bool empty() const;

ukuran_maksimum(tidak umum digunakan): kembalidaftar tertautJumlah maksimum elemen yang dapat ditampung oleh wadah.
(Karena keterbatasan implementasi sistem atau perpustakaan, ini adalah potensi maksimum yang dapat dicapai oleh sebuah wadahukuran , namun tidak ada jaminan bahwa kontainer akan mencapai ukuran tersebut: kontainer mungkin masih tidak dapat mengalokasikan penyimpanan kapan pun sebelum mencapai ukuran tersebut. )

size_type max_size() const;

mengubah ukuran:Ubah ukuran wadah untuk menampungnyaNelemen.
jikaNlebih kecil dari wadah saat iniukuran, konten akan dikurangi ke sebelumnyaNelemen, menghilangkan elemen yang melebihi (dan menghancurkannya).
jikaNLebih besar dari kontainer saat iniukuran, lalu konten diperluas dengan memasukkan jumlah elemen yang diperlukan di akhir untuk mencapainyaN ukuran dari.Jika ditentukannilai, maka elemen baru akan diinisialisasinilaisalinan, jika tidak, salinan tersebut akan diinisialisasi nilai.
(Perhatikan bahwa fungsi ini mengubah isi sebenarnya dari wadah dengan menyisipkan atau menghapus elemen dari wadah.)

void resize (size_type n, value_type val = value_type());

Misalnya:

  1. void test()
  2. {
  3. list<int> lt(3, 1);
  4. /*list<int> lt1(lt);*/
  5. list<int> lt1(lt.begin(), lt.end());
  6. list<int> lt2;
  7. cout << lt1.size() <<endl;
  8. cout << lt1.empty() <<endl;
  9. cout << lt2.empty() <<endl;
  10. lt1.resize(10);
  11. cout << lt1.size() << endl;
  12. for (auto i : lt1)
  13. {
  14. cout << i << " ";
  15. }
  16. }

hasil operasi:

3. Akses umum dan traversal

1.Iterator

  1. iterator begin();
  2. const_iterator begin() const;
  3. iterator end();
  4. const_iterator end() const;

Iterator: digunakan untuk mendapatkan posisi node pertama dan node terakhir pada linked listPosisi berikutnya (yaitu posisi penjaga)

Misalnya:

  1. void test()
  2. {
  3. list<int> lt(5, 2);
  4. list<int> ::iterator it = lt.begin();
  5. while (it != lt.end())
  6. {
  7. cout << *it << " ";
  8. ++it;
  9. }
  10. }

hasil operasi:

2. Membalikkan iterator

iterator_terbalik rbegin();

const_reverse_iterator rbegin() const;

iterator_terbalik rend();

const_reverse_iterator rend() const;

Membalikkan iterator, rbegin mendapatkan posisi node terakhir di container, rend mendapatkan posisi bit sentinel di container

  1. void test()
  2. {
  3. list<int> lt = { 1,23,4,4,5,2 };
  4. list<int> ::reverse_iterator rit = lt.rbegin();
  5. while (rit != lt.rend())
  6. {
  7. cout << *rit << " ";
  8. ++rit;
  9. }
  10. }

hasil operasi:

Catatan: Rit iterator terbalik juga harus menggunakan ++ alih-alih --

3.depan dan belakang

depan:

referensi depan();

const_referensi depan() const;

Mengembalikan referensi ke data yang disimpan di node pertama dalam daftar tertaut

kembali:

referensi kembali();

const_referensi kembali() const;

Mengembalikan referensi ke data yang disimpan di node terakhir dalam daftar tertaut

Misalnya:

  1. void test()
  2. {
  3. list<int> lt = {213123,123,34524,213};
  4. cout << lt.front() << endl;
  5. cout << lt.back() << endl;
  6. }

hasil operasi:

4.Tambahkan, hapus, periksa dan ubah daftar

1) dorong_depan dan pop_depan

push_front disebut penyisipan kepala, memasukkan elemen dari kepala daftar tertaut

void push_front(const nilai_tipe& val);

pop_front disebut penghapusan kepala, yang menghapus elemen dari kepala daftar tertaut.

batal pop_depan();

void pop_front();

Misalnya:

  1. void test()
  2. {
  3. list<int> lt = {213123,123,34524,213};
  4. cout << lt.front() << endl;
  5. lt.push_front(21345);
  6. cout << lt.front() << endl;
  7. lt.pop_front();
  8. cout << lt.front() << endl;
  9. }

hasil operasi:

2) push_back dan pop_back

push_back disebut penyisipan ekor, menyisipkan elemen dari akhir daftar tertaut

void push_back(const nilai_tipe& val);

pop_back disebut penghapusan ekor, yang menghapus elemen dari akhir daftar tertaut.

batal pop_back();

Misalnya:

  1. void test()
  2. {
  3. list<int> lt = {213123,123,34524,213};
  4. cout << lt.back() << endl;
  5. lt.push_back(21345);
  6. cout << lt.back() << endl;
  7. lt.pop_back();
  8. cout << lt.back() << endl;
  9. }

hasil operasi:

3) temukan

  1. template <class InputIterator, class T>
  2. InputIterator find(InputIterator first, InputIterator last, const T& val);

Temukan val di kisaran dua iterator dan kembalikan iterator ke tempatnya

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 3; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. list<int>::iterator pos = find(lt.begin(), lt.end(), 1);
  9. *pos = 114514;
  10. for (auto i : lt)
  11. {
  12. cout << i << " ";
  13. }
  14. }

hasil operasi:

Catatan: Fungsi ini bukan fungsi anggota daftar, tetapi fungsi di perpustakaan standar. Beberapa kontainer berbagi fungsi find.

Seperti yang Anda lihat, kita dapat langsung melakukan dereferensi iterator daftar dan mengubah kontennya, tetapi bukankah iterator harus menunjuk ke node? Mengapa dereferensi dapat mengubah data?

Faktanya, iterator daftar tidak disimulasikan dan diimplementasikan menggunakan penunjuk ekologi asli, dan perlu diringkas di bagian bawah, yang akan tercermin dalam kode sumber implementasi simulasi daftar.

4)masukkan

iterator sisipan(posisi iterator, const tipe_nilai& val);

void insert(posisi iterator, ukuran_tipe n, const tipe_nilai& val);

————————————————————————————————————————

templat<class InputIterator>

void insert(posisi iterator, InputIterator pertama, InputIterator terakhir);

Sisipkan satu atau lebih elemen di depan posisi

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 3; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. list<int>::iterator pos = find(lt.begin(), lt.end(), 1);
  9. lt.insert(pos, 8848);
  10. for (auto i : lt)
  11. {
  12. cout << i << " ";
  13. }
  14. }

hasil operasi:

Siswa yang cermat mungkin telah menemukan bahwa operasi penyisipan daftar adalahTidak akan menyebabkan iterator menjadi tidak valid, karena node yang ditunjuk oleh pos tetap tidak berubah dan posisi relatifnya tidak berubah.

Namun, operasi penghapusan daftar pasti akan menyebabkan iterator menjadi tidak valid, dan hanya iterator yang menunjuk ke node yang dihapus yang akan menjadi tidak valid, dan iterator lainnya tidak akan terpengaruh.

5) menghapus

  1. iterator erase(iterator position);
  2. iterator erase(iterator first, iterator last);

Hapus elemen pada posisi atau semua elemen dalam rentang [pertama, terakhir)

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 3; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. list<int>::iterator pos = find(lt.begin(), lt.end(), 1);
  9. lt.erase(lt.begin());
  10. for (auto i : lt)
  11. {
  12. cout << i << " ";
  13. }
  14. }

hasil operasi:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 3; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. list<int>::iterator pos = find(lt.begin(), lt.end(), 2);
  9. lt.erase(lt.begin(),pos);
  10. for (auto i : lt)
  11. {
  12. cout << i << " ";
  13. }
  14. }

hasil operasi:

6) tukar

void swap(vektor& x);

Tukar dua objek daftar

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. list<int> lt2(6, 12);
  5. for (int i = 0; i < 10; i++)
  6. {
  7. lt.push_back(i);
  8. }
  9. lt.swap(lt2);
  10. for (auto i : lt2)
  11. {
  12. cout << i << " ";
  13. }
  14. cout << endl;
  15. }

hasil operasi:

7)menetapkan

templat<class InputIterator>

void assign(InputIterator pertama, InputIterator terakhir);

void assign(jenis_ukuran n, const jenis_nilai& val);

Tentukan konten baru untuk daftar, ganti konten saat ini dan ubah jumlah node

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 10; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. lt.assign(4, 0);
  9. for (auto i : lt)
  10. {
  11. cout << i << " ";
  12. }
  13. }

hasil operasi:

8)jelas

batal hapus();

Hapus semua node dalam daftar tertaut

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 10; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. lt.clear();
  9. cout << lt.size() << endl;
  10. }

hasil operasi:

5. Daftar antarmuka modifikasi pesanan

(1)menyortir

batal sort();

templat<class Compare>

void sort(Bandingkan comp);

Karena kekhasan struktur daftar, fungsi pengurutan di perpustakaan standar tidak dapat digunakan, karena iterator tidak dapat melakukan operasi pengurangan.

Dan dalam dokumentasi C++, kita dapat melihat bahwa sortir di perpustakaan standar juga membatasi jenis iterator menjadi akses acak (RandomAccess)

  1. default (1)
  2. template <class RandomAccessIterator>
  3. void sort (RandomAccessIterator first, RandomAccessIterator last);
  4. custom (2)
  5. template <class RandomAccessIterator, class Compare>
  6. void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

Iterator memiliki beberapa kategori fungsional:

  • Iterator satu arah, hanya dapat melakukan ++
  • Iterator dua arah, bisa ++ dan --
  • Iterator acak, bisa ++, --, + dan -

Namun, fungsi pengurutan daftar tidak diperlukan, karena efisiensi pengurutan daftar tertaut secara langsung jauh lebih lambat daripada menyalin ke vektor, mengurutkan, dan kemudian menyalin kembali ke daftar tertaut.

(2)balik

template <class BidirectionalIterator>
  void reverse (BidirectionalIterator first, BidirectionalIterator last);

Balikkan daftar tertaut

Misalnya:

  1. void test()
  2. {
  3. list<int> lt;
  4. for (int i = 0; i < 10; i++)
  5. {
  6. lt.push_back(i);
  7. }
  8. for (auto i : lt)
  9. {
  10. cout << i << " ";
  11. }
  12. cout << endl;
  13. lt.reverse();
  14. for (auto i : lt)
  15. {
  16. cout << i << " ";
  17. }
  18. cout << endl;
  19. }

hasil operasi:


Jika ada kesalahan, mohon koreksi saya.