pointer,linkedlist , sorting and searching di c++
POINTER

Diterbitkan oleh Juan Soulie

Memori komputer Anda dapat bayangkan sebagai suksesi dari memori sel, setiap salah satu ukuran minimal komputer yang mengelola (satu byte). Ini single-byte memori sel diberi nomor berturut-turut dalam perjalanan, sehingga, di setiap blok memori, setiap sel memiliki nomor yang sama seperti sebelumnya ditambah satu.

Dengan cara ini, masing-masing sel dapat dengan mudah yang terletak di memori karena ia memiliki alamat unik dan semua memori sel mengikuti pola berturut-turut. Misalnya, jika kita mencari sel 1776 kita tahu bahwa itu akan segera sel antara 1775 dan 1777, tepat setelah satu sel 776 ribu dan tepat satu ribu sel sel sebelum 2776.
Operator referensi (&)
Segera setelah kami menyatakan variabel, jumlah memori yang diperlukan untuk ditempatkan di lokasi tertentu di memori (alamat memori nya). Kami biasanya tidak aktif memutuskan lokasi yang tepat dari variabel dalam panel sel-sel yang kita bayangkan memori menjadi – Untungnya, tugas yang dilakukan secara otomatis oleh sistem operasi pada saat runtime. Namun, dalam beberapa kasus kami mungkin akan tertarik mengetahui alamat variabel di mana kita sedang disimpan selama runtime untuk beroperasi dengan posisi relatif ke.

Alamat yang locates variabel dalam memori apa yang kita panggil adalah referensi ke variabel. Ini referensi ke variabel dapat diperoleh sebelumnya pengenal dari variabel dengan tanda ampersand (&), yang dikenal sebagai referensi operator, dan yang dapat secara harfiah diterjemahkan sebagai “alamat”. Sebagai contoh:
ted = &andy;

Hal ini akan memberikan ted ke alamat variabel andy, sejak saat sebelum nama variabel andy dengan operator referensi (&), kita tidak lagi berbicara mengenai isi dari variabel itu sendiri, tetapi mengenai referensi (yaitu, dengan alamat di memori).

Dari sekarang kita akan menganggap bahwa andy selama runtime ditempatkan dalam memori alamat 1776. Nomor ini (1776) hanya sebuah asumsi acak inventing kita sekarang untuk membantu menjelaskan beberapa konsep dalam tutorial ini, namun pada kenyataannya, kita tidak bisa tahu sebelum runtime yang nyata nilai alamat variabel akan ada dalam memori.

Mempertimbangkan penggalan kode berikut:
andy = 25;
fred = andy;
ted = &andy;

Nilai-nilai dalam setiap variabel setelah pelaksanaan ini, akan ditampilkan pada diagram berikut:

Pertama, kami telah diberi nilai 25 ke andy (variabel yang di alamat memori kami telah dianggap 1776).

Pernyataan yang kedua disalin ke fred isi variabel andy (yang 25). Ini adalah tugas operasi standar, seperti yang kita telah melakukannya banyak kali sebelumnya.

Akhirnya, ketiga pernyataan salinan ke ted tidak nilai dalam andy tetapi referensi tersedia (misalnya, alamat-nya, yang kami telah dianggap 1776). Alasan ini adalah yang ketiga dalam tugas operasi kami telah mendahului pengenal andy dengan operator referensi (&), jadi kami tidak lagi merujuk kepada nilai andy tapi referensi-nya (alamat nya di memori).

Variabel yang menyimpan referensi ke variabel lain (seperti ted di contoh sebelumnya) adalah apa yang kami memanggil pointer. Pointer adalah fitur yang sangat kuat dari C + + bahasa yang banyak digunakan dalam program lanjutan. Jauh ke depan, kita akan melihat bagaimana ini jenis variabel yang digunakan dan diumumkan.
Dereference operator (*)

Kami baru saja terlihat bahwa variabel yang menyimpan referensi ke variabel lain yang disebut pointer. Pointer yang berkata “untuk” variabel referensi yang mereka simpan.

Menggunakan pointer kita dapat langsung mengakses nilai yang tersimpan dalam variabel yang menunjuk ke. Untuk melakukan ini, kami hanya harus mendahului yang pointer dari identifier dengan asterisk (*), yang bertindak sebagai operator dan dereference yang dapat diterjemahkan secara harfiah ke “nilai yang oleh”.

Oleh karena itu, berikut dengan nilai-nilai sebelumnya contoh, jika kita menulis:
beth = * ted;

(yang kita dapat dibaca sebagai: “beth sama dengan nilai yang oleh ted”) beth akan mengambil nilai 25, adalah ted sejak 1776, dan nilai yang oleh 1776 adalah 25.

Anda harus membedakan dengan jelas bahwa ekspresi ted merujuk pada nilai 1776, sedangkan * ted (dengan tanda bintang * sebelumnya pengenal) merujuk kepada nilai yang disimpan pada alamat 1776, yang dalam hal ini adalah 25. Perhatikan perbedaan yang termasuk atau tidak termasuk dereference operator (termasuk saya ada yang jelas komentar tentang bagaimana masing-masing dua kalimat dapat dibaca):
beth = ted; / / beth sama ted (1776) beth = * ted; / / beth sama dengan nilai yang oleh ted (25)

Perhatikan perbedaan antara referensi dan dereference operator:
• & Merupakan acuan operator dan dapat dibaca sebagai “alamat”
• * Adalah dereference operator dan dapat dibaca sebagai “nilai yang oleh”
Oleh karena itu, mereka saling melengkapi (atau berlawanan) arti. J dirujuk dengan variabel & dapat dengan dereferenced *.

Sebelumnya kami melaksanakan tugas operasi dua berikut:
andy = 25;
ted = &andy;

Tepat setelah dua pernyataan ini, semua hal-hal berikut ekspresi benar akan memberikan hasil sebagai:
andy == 25
& andy == 1776
ted == 1776
* ted == 25

Ekspresi pertama cukup jelas mengingat bahwa tugas operasi yang dilaksanakan di andy andy = 25. Kedua menggunakan satu operator referensi (&), yang kembali alamat variabel andy, yang kita ini dianggap memiliki nilai 1776. Yang ketiga adalah agak jelas sejak kedua ungkapan itu benar dan penugasan operasi dilakukan pada ted adalah ted = & andy. Keempat ekspresi menggunakan operator dereference (*) itu, karena kami baru saja mulai, dapat dibaca sebagai “nilai yang oleh”, dan nilai yang benar-benar oleh ted 25.

Jadi, setelah semua itu, Anda juga dapat mengambil kesimpulan bahwa sepanjang alamat yang tetap tidak berubah oleh ted ekspresi berikut ini juga akan menjadi kenyataan:
* ted == andy

Menyatakan variabel pointer dari jenis
Karena kemampuan dari pointer secara langsung merujuk kepada nilai yang ke poin, menjadi penting untuk menentukan dalam deklarasi yang tipe data pointer yang akan menunjuk ke. Ianya bukan hal yang sama untuk menunjuk ke sebuah char sebagai untuk menunjuk ke sebuah int atau float.

Deklarasi pointer dari format berikut ini:

Jenis * nama;

dimana jenis data jenis nilai bahwa pointer dimaksudkan untuk mengarah ke. Jenis ini bukan merupakan jenis pointer sendiri! tetapi tipe data pointer yang menunjuk ke. Sebagai contoh:
int * number;
char * character;
float * greatnumber;

Ini adalah tiga deklarasi dari pointer. Masing-masing ditujukan untuk menunjuk ke jenis data yang berbeda, namun sebenarnya semua itu adalah pointer dan semua itu akan menempati jumlah yang sama dalam ruang memori (ukuran memori dari pointer tergantung pada platform dimana kode ini terjadi berjalan). Namun demikian, data yang mereka untuk tidak memenuhi jumlah yang sama dan tidak ada ruang yang sama jenis: yang pertama menunjuk ke sebuah int, yang kedua satu ke char dan terakhir ke float. Oleh karena itu, walaupun tiga contoh variabel adalah semua dari mereka yang menempati pointer ukuran yang sama di memori, mereka dikatakan memiliki berbagai tipe: int *, char * * hanyut dan masing-masing, tergantung pada jenis mereka ke titik.

Saya ingin menekankan bahwa tanda asterisk (*) yang menyatakan bila kita menggunakan sebuah pointer hanya berarti bahwa ia adalah pointer (yang merupakan bagian dari jenis senyawa specifier), dan tidak boleh dengan dereference operator yang telah kami melihat sedikit lebih dulu, tetapi yang juga ditulis dengan tanda bintang (*). Mereka hanya diwakili dua hal yang berbeda dengan tanda yang sama.

Sekarang telah melihat kode ini:
/ / My first pointer # include menggunakan namespace std; int main () (int firstvalue, secondvalue; int * mypointer; mypointer = &firstvalue; * mypointer = 10; mypointer = & secondvalue; * mypointer = 20; cout << " firstvalue adalah "<<<<" secondvalue adalah "<<
secondvalue adalah 20

Perhatikan bahwa meskipun kami tidak pernah secara langsung menetapkan nilai baik firstvalue atau secondvalue, keduanya berakhir dengan nilai set langsung melalui penggunaan mypointer. Prosedur ini adalah:

Pertama, kami telah ditetapkan sebagai nilai mypointer referensi ke firstvalue menggunakan operator referensi (&). Dan kemudian kami memiliki nilai 10 yang ditugaskan ke lokasi memori yang oleh mypointer, bahwa karena saat ini adalah yang menunjuk ke lokasi memori firstvalue, ini sebenarnya memodifikasi nilai firstvalue.

Dalam rangka untuk menunjukkan bahwa pointer dapat mengambil nilai yang berbeda selama beberapa program yang sama saya telah berulang kali dengan proses yang sama secondvalue dan pointer, mypointer.

Berikut ini adalah contoh sedikit lebih dijabarkan:
/ / Lebih pointer # include menggunakan namespace std; int main () (int firstvalue = 5, secondvalue = 15; int * p1, * p2; p1 = &firstvalue; / / p1 = alamat firstvalue p2 = & secondvalue; / / p2 = alamat secondvalue * p1 = 10; / / nilai yang oleh p1 = 10 * p2 = * p1; / / nilai yang oleh p2 = nilai yang oleh p1 p1 = p2; / / p1 = p2 (nilai pointer adalah disalin) * p1 = 20; / / nilai yang oleh p1 = 20 cout << "firstvalue adalah" <<<< "secondvalue adalah" <<
secondvalue adalah 20

Aku telah dimasukkan sebagai komentar pada setiap baris kode bagaimana dapat dibaca: ampersand (&) sebagai "alamat" dan asterisk (*) sebagai "nilai yang oleh".

Pemberitahuan bahwa ada ekspresi dengan pointer p1 dan p2, baik dengan dan tanpa dereference operator (*). Arti dari sebuah ekspresi dengan menggunakan operator dereference (*) sangat berbeda dari satu yang tidak: Saat ini operator yang precedes pointer nama, ekspresi merujuk kepada nilai yang tajam, sementara bila muncul nama pointer tanpa operator ini, ia merujuk dengan nilai dari pointer itu sendiri (yaitu alamat apa adalah pointer yang menunjuk ke).

Hal lain yang dapat anda perhatian adalah baris:
int * p1, * p2;

Ini menyatakan dua pointer yang digunakan dalam contoh sebelumnya. Tetapi pemberitahuan bahwa terdapat tanda bintang (*) untuk setiap pointer, dalam rangka untuk kedua jenis memiliki int * (pointer ke int).

Jika tidak, untuk kedua jenis variabel yang dinyatakan dalam baris yang telah int (dan tidak int *) karena hubungan diutamakan. Jika kami telah tertulis:
int * p1, p2;

p1 memang akan ada int * jenis, akan tetapi ada jenis p2 int (spasi tidak peduli sama sekali untuk tujuan ini). Hal ini disebabkan oleh operator diutamakan aturan. Tapi bagaimanapun, cukup mengingat bahwa anda harus meletakkan satu per asterisk pointer adalah pointer cukup untuk sebagian besar pengguna.
Pointer dan array
Konsep array sangat terikat pada salah satu pointer. Sebenarnya, array identifier yang setara dengan alamat dari elemen pertama, pointer sebagai setara dengan alamat dari elemen pertama yang ke poin, jadi mereka sebenarnya adalah konsep yang sama. Misalnya, jika seandainya kedua deklarasi:
int angka [20];
int * p;

Berikut tugas operasi akan berlaku:
p = nomor;

Setelah itu, p dan nomor akan sama dan akan memiliki properti yang sama. Satu-satunya perbedaan adalah bahwa kita dapat mengubah nilai pointer p lain satu, sedangkan nomor akan selalu menunjuk ke pertama dari 20 jenis elemen int yang telah ditetapkan. Oleh karena itu, tidak seperti p, yang merupakan pointer biasa, angka adalah array, dan array dapat dianggap konstan pointer. Oleh karena itu, berikut alokasi tidak akan berlaku:
nomor = p;

Karena angka adalah array, sehingga beroperasi sebagai pointer konstan, dan kita tidak dapat menetapkan nilai-nilai konstan.

Karena karakteristik dari variabel, yang mencakup semua ekspresi pointer dalam contoh berikut adalah hal yang berlaku:
/ / Lebih pointer
# include
menggunakan namespace std;

int main ()
(
int nomor [5];
int * p;
p = nomor; * p = 10;
p + +; * p = 20;
p = & nomor [2]; * p = 30;
p = numbers + 3; * p = 40;
p = nomor; * (p 4) = 50;
for (int n = 0; n <5; n + +)
cout <<< ",";
return 0;
)
10, 20, 30, 40, 50,

Dalam bab tentang array kita gunakan kurung ([]) beberapa kali untuk menentukan indeks dari sebuah elemen array yang ingin kita lihat. Well, ini Braket operator tanda [] yang juga dikenal sebagai operator dereference offset operator. Mereka dereference variabel mereka mengikuti * seperti ini, tetapi juga menambah jumlah antara kurung ke alamat yang dereferenced. Sebagai contoh:
a [5] = 0; / / a [offset dari 5] = 0
* (a +5) = 0; / / cerucup oleh (a +5) = 0

Kedua kalimat yang setara dan berlaku jika kedua adalah pointer atau jika adalah array.
Pointer initialization
Ketika kami menyatakan pointer mungkin ingin secara eksplisit menentukan variabel yang kita ingin mereka untuk:
int nomor;
int * tommy = &number;

Perilaku ini adalah setara dengan kode:
int nomor;
int * tommy;
tommy = &number;

Bila pointer initialization berlangsung kita selalu menempatkan nilai dengan referensi ke tempat pointer poin (tommy), tidak pernah menjadi nilai yang (* tommy). Anda harus mempertimbangkan bahwa pada saat ini yang menyatakan sebuah pointer, maka asterisk (*) menunjukkan bahwa itu hanya sebuah pointer, itu bukan dereference operator (walaupun kedua menggunakan tanda yang sama: *). Ingat, mereka adalah dua fungsi yang berbeda satu tanda. Oleh karena itu, kita harus berhati-hatilah agar tidak membingungkan sebelumnya dengan kode:
int nomor;
int * tommy;
* tommy = &number;

yang tidak benar, dan bagaimanapun tidak akan ada banyak rasa dalam hal ini jika anda berpikir tentang hal ini.

Seperti dalam kasus array, compiler memungkinkan hal khusus yang ingin kita initialize konten di mana pointer poin dengan konstan pada saat pointer dinyatakan:
char * terry = "hello";

Dalam hal ini, ruang memori digunakan untuk berisi "hello" dan maka pointer ke karakter pertama dari memori ini blok diberikan ke terry. Jika kita bayangkan bahwa "hello" disimpan pada lokasi memori alamat yang dimulai pada 1702, kami dapat mewakili sebelumnya pernyataan sebagai berikut:

Penting untuk menunjukkan bahwa terry berisi nilai 1702, dan bukan 'h' atau "hello", walaupun memang 1702 adalah alamat kedua.

Terry pointer yang mengarah ke urutan karakter dan dapat dibaca sebagai jika ia array (ingat bahwa array adalah seperti konstan pointer). Sebagai contoh, kami dapat mengakses kelima elemen array dengan salah satu dari dua ekspresi:
* (terry +4)
terry [4]

Keduanya memiliki nilai ekspresi dari 'o' (yang kelima elemen array).
Pointer arithmetics

Ilmu hitung untuk melakukan operasi pada pointer adalah sedikit berbeda dari mereka untuk melakukan integer biasa pada jenis data. Untuk mulai dengan, hanya penambahan dan pengurangan operasi boleh dilakukan dengan mereka, yang lain tidak membuat rasa dalam dunia pointer. Selain namun kedua dan pengurangan perilaku yang berbeda dengan pointer sesuai dengan ukuran jenis data yang mereka titik.

Apabila kita melihat berbagai jenis data fundamental, kami melihat bahwa beberapa menempati ruang lebih atau kurang daripada yang lain dalam memori. Sebagai contoh, mari kita asumsikan bahwa dalam suatu compiler untuk mesin tertentu, char mengambil 1 byte, 2 byte berlangsung singkat dan memerlukan waktu lama 4.

Misalnya kita menetapkan tiga pointer dalam kompiler ini:
char * mychar;
* singkat myshort;
* mylong panjang;

dan yang kita tahu bahwa mereka menunjuk ke lokasi memori 1000, 2000 dan 3000 masing-masing.

Jadi jika kita menulis:
mychar + +;
myshort + +;
mylong + +;

mychar, karena dapat diharapkan, akan berisi nilai 1001. Tetapi tidak begitu jelas, myshort akan berisi nilai 2002, dan akan mylong berisi 3004, walaupun mereka telah meningkat masing-masing hanya sekali. Sebabnya adalah saat menambahkan satu pointer ke kami sehingga untuk hal-hal berikut ke elemen yang sama dengan jenis yang telah ditetapkan, dan oleh karena itu ukuran byte dari jenis yang akan ditambahkan ke pointer.

Hal ini berlaku baik saat menambahkan dan subtracting apapun ke nomor pointer. Itu akan terjadi persis sama jika kita menulis:
mychar = mychar + 1;
myshort = myshort + 1;
mylong = mylong + 1;

Kedua peningkatan (+ +) dan penurunan (-) operator memiliki operator lebih diutamakan daripada dereference operator (*), namun keduanya mempunyai perilaku khusus bila digunakan sebagai suffix (ekspresi dievaluasi dengan nilai itu sebelum meningkat) . Oleh karena itu, berikut ekspresi dapat mengakibatkan kebingungan:
* p + +

+ + Karena telah lebih diutamakan daripada *, ini adalah setara dengan ekspresi * (p + +). Karena itu, apa yang ia adalah untuk meningkatkan nilai p (jadi sekarang poin ke elemen berikutnya), tetapi karena + + yang digunakan sebagai ekspresi postfix seluruh dievaluasi sebagai nilai yang asli oleh referensi (pointer pada alamat yang untuk sebelum meningkat).

Perhatikan perbedaan dengan:

(* p) + +

Di sini, ungkapan yang telah dievaluasi sebagai nilai yang meningkat oleh p per satu. Nilai p (dengan pointer sendiri) tidak akan diubah (apa yang sedang dimodifikasi adalah apa yang sedang ke ini pointer).

Jika kita menulis:
* p + + = * q + +;

+ + Karena memiliki lebih diutamakan daripada *, kedua p dan q akan meningkat, namun karena keduanya meningkatkan operator (+ +) digunakan sebagai postfix dan bukan awalan, nilai yang diberikan untuk * p * q adalah sebelum kedua p dan q adalah peningkatan . Kemudian keduanya meningkat. Ia akan setara dengan kira-kira:
* * q = p;
+ + p;
q + +;

Seperti biasa, saya sarankan Anda untuk menggunakan tanda kurung () untuk menghindari hasil yang tak terduga dan memberi lebih mudah dibaca dengan kode.
Pointer ke pointer
C + + memungkinkan penggunaan pointer yang mengarah ke pointer, bahwa, pada gilirannya, titik data (atau bahkan lainnya pointer). Untuk melakukan itu, kita hanya perlu menambahkan sebuah asterisk (*) untuk setiap tingkat acuan dalam deklarasi:
char a; char * b; char ** c; a = 'z'; &a; b = c = &b;

Ini, andai kata yang dipilih secara acak lokasi memori untuk setiap variabel dari 7230, 8092 dan 10502, dapat digambarkan sebagai berikut:

Nilai setiap variabel yang tertulis di dalam setiap sel; di bawah sel yang masing-masing alamat di memori.

Yang baru dalam hal ini adalah contoh variabel c, yang dapat digunakan dalam tiga tingkatan yang berbeda dari tipuan, setiap satu dari mereka akan sesuai dengan nilai yang berbeda:
• c memiliki tipe char ** dan nilai 8092
• * c memiliki tipe char * dan nilai 7230
• ** c tipe char dan memiliki nilai 'z'

void pointer
The void jenis pointer adalah tipe khusus dari pointer. Dalam C + +, void mewakili ketiadaan jenis, sehingga void pointer adalah pointer yang mengarah ke nilai yang tidak memiliki jenis (dan dengan demikian juga seorang yg tak dpt ditentukan panjang dan yg tak dpt ditentukan dereference properti).

Hal ini memungkinkan void pointer untuk menunjuk ke setiap jenis data, dari nilai integer atau float ke string karakter. Namun dalam pertukaran besar mereka memiliki keterbatasan: data oleh mereka yang tidak dapat langsung dereferenced (yang logis, karena kita tidak memiliki tipe dereference ke), dan untuk itu kami akan selalu dilemparkan ke alamat di void pointer ke beberapa jenis lainnya pointer yang menunjuk ke suatu jenis data konkret dereferencing sebelum itu.

Menggunakan salah satu mungkin untuk lulus generik parameter ke fungsi:
/ / Increaser
# include
menggunakan namespace std;

meningkatkan void (void * data, int psize)
(
if (psize == sizeof (char))
(Char * pchar; pchar = (char *) data; + + (* pchar);)
else if (psize == sizeof (int))
(Int * pint; pint = (int *) data; + + (* pint);)
)

int main ()
(
char a = 'x';
int b = 1602;
meningkatkan (& a, sizeof (a));
meningkatkan (& b, sizeof (b));
cout <<< "," <<
return 0;
)
y, 1603

sizeof merupakan operator terpadu dalam bahasa C + + yang kembali ukuran byte dari parameter. Untuk non-data dinamis jenis ini adalah nilai konstan. Oleh karena itu, misalnya, sizeof (char) adalah 1, karena merupakan salah satu jenis char byte panjang.
Null pointer
J null pointer adalah biasa pointer pointer dari setiap jenis yang memiliki nilai khusus yang menunjukkan bahwa tidak ada yang berlaku untuk referensi memori atau alamat. Nilai ini merupakan hasil dari jenis-casting dengan nilai integer nol untuk semua jenis anjing.
int * p;
p = 0; / / p memiliki nilai null pointer

Don't confuse null pointer dengan void pointer. J null pointer adalah nilai yang dapat berlangsung setiap pointer untuk mewakili bahwa pointing ke "nowhere", sementara void pointer adalah jenis anjing khusus yang dapat menunjuk ke suatu tempat tanpa jenis tertentu. Satu merujuk kepada nilai yang disimpan dalam pointer sendiri dan lainnya untuk jenis data ini ke poin.
Pointer ke fungsi
C + + memungkinkan operasi dengan pointer ke fungsi. Yang biasa menggunakan ini untuk melewati salah satu fungsi sebagai argumen ke fungsi lainnya, karena ini tidak dapat disahkan dereferenced. Untuk menyatakan suatu pointer ke salah satu fungsi kita harus menyatakan hal seperti prototipe dari fungsi kecuali bahwa nama fungsi ini ditutupi antara tanda kurung () dan tanda bintang (*) dimasukkan sebelum nama:
/ / Pointer ke fungsi
# include
menggunakan namespace std;

Selain int (int a, int b)
(Return (a + b);)

int pengurangan (int a, int b)
(Return (ab);)

int operation (int x, int y, int (* functocall) (int, int))
(
int g;
g = (* functocall) (x, y);
return (g);
)

int main ()
(
int m, n;
int (* minus) (int, int) = pengurangan;

operasi m = (7, 5, tambahan);
n = operasi (20, m, minus);
cout Selanjutnya = Daftar baru;
Tail = tail-> Selanjutnya;
)

Di sini kita menambahkan node pada akhir daftar kami, maka Tail memindahkan pointer ke titik yang baru contoh! Setelah fungsi ini kita selalu dapat kita akses melalui node baru Tail sejak kami baru dialokasikan contoh, kemudian dibuat Tail point to it!

Traversing yang Daftar

Ini sebenarnya adalah bagian paling sulit dalam berurusan dengan satu Linked Lists. Hal ini disebabkan karena kami tidak dapat segera mengakses node sebelumnya harus kita perlu, seperti bila kita ingin menghapus node dan kembali ke node sebelum node setelah satu tidak dihapus. Salah satu cara yang lebih mudah untuk menciptakan sebuah fungsi yang akan menyeberang melalui daftar yang diberikan jumlah node. Dengan cara ini, kita dapat menyimpan satu yang harus kita tentang kita perlu menghapusnya, maka kita bisa melewati node ke fungsi dan mendapatkan pointer ke node sebelumnya! Seperti ini:
ListPtr SLList:: Sebelumnya (panjang indeks)
(Temp = ListPtr Kepala;
for (long count = 0; count
(temp = temp-> Selanjutnya;
)
return temp;
)

ListPtr SLList:: Sebelumnya (ListPtr indeks)
(Temp = ListPtr Kepala;
if (index == Kepala) / / hal khusus, indeks IS kepala:)
(Return Kepala;
)

while (temp-> Selanjutnya! = indeks)
(Temp = temp-> Selanjutnya;
)
return temp;
)

Jika kita tahu bahwa kami telah pergi ke dalam daftar tertentu jumlah node, kami dapat melewati angka yang kami Sebelumnya fungsi dan mendapatkan pointer ke node sebelumnya. Ini bekerja dengan baik, tetapi sulit untuk debug kita harus turun di counter dll kedua saya membuat sebuah versi yang dapat digunakan untuk melewati node Anda sedang di sebagai argumen, maka kita dapat benar-benar yakin bahwa kami akan mendapatkan node sebelumnya ! Yang kedua saya menggunakan versi yang lebih LOT. Juga menyadari bahwa kedua telah memeriksa kesalahan. Jika kita sedang di Head node dan mencoba untuk kembali satu, ia hanya kembali Kepala daripada kembali sampah.

Sewaktu membuat kami neeto kelas, saya memutuskan untuk menggunakan satu kelas node pointer yang dinyatakan kami di CurrentPtr. Untuk itu, saya membuat dua fungsi yang kita pointer bergerak maju dan kembali satu node. Jika kita di bagian kepala dan mencoba untuk kembali satu node (menjadi tidak ada), maka fungsi tidak memindahkan pointer kami. Demikian juga jika kita pada akhir daftar dan mencoba untuk maju ke node berikutnya (tidak ada), maka kami tidak memindahkan pointer.

void SLList:: Advance ()
(If (CurrentPtr-> Berikut = NULL)
(CurrentPtr = CurrentPtr-> Selanjutnya;
)
)

void SLList:: mundur cepat ()
(If (CurrentPtr! = Kepala)
Sebelumnya CurrentPtr = ((CurrentPtr);
)
)

Menghapus Node

Saat menghapus node yang terhubung dari daftar, terdapat 3 kasus yang berbeda untuk memutuskan dari. Node yang akan dihapus adalah kepala node, it’s a node tengah (entah antara kepala atau ekor, tetapi tidak baik) atau dapat menjadi node ekor. Setiap memerlukan perubahan kecil untuk memperhitungkan saat menghapus node. Mari kita pergi lebih mendalam di masing-masing.
void SLList:: DeleteANode (ListPtr mayat) // Selanjutnya;
menghapus temp;
)
else if (jenazah == Tail) / / 2 kasus mayat adalah pada akhir
(Temp = Tail;
Sebelumnya tail = (Tail);
Tail-> Berikut = NULL;
menghapus temp;
)
else / / 3 kasus mayat yang di tengah suatu
(temp = Sebelumnya (jenazah);
temp-> Selanjutnya = mayat-> Selanjutnya;
menghapus jenazah;
)

CurrentPtr = Kepala; / / RESET kelas tempptr
)

CurrentNode sebenarnya mayat

Kasus 1: CurrentNode = Kepala Node

Dalam hal ini, node yang akan dihapus sebenarnya Kepala node! Ini adalah kasus khusus karena tidak ada sebelumnya untuk menghubungkan node. Kami hanya menggunakan kami temp pointer yang perlu diingat adalah tempat yang di Kepala, muka Kepala ke posisi berikutnya, maka kami menghapus lokasi disimpan! Sederhana huh!

Kasus 2: CurrentNode node = Akhir

Dalam hal ini, node yang akan dihapus sebenarnya adalah node Tail! Ini adalah kasus khusus karena kami memiliki node sebelumnya, namun tidak ada node setelahnya untuk menyambung ke. Kami menyimpan lama lokasi Tail menggunakan temp, menetapkan Tail sama dengan sebelumnya node, mengatur Berikut pointer dari Tail sama NULL karena pada akhirnya, maka kita hapus temp pointer!

Kasus 3: CurrentNode adalah somwhere di antara

Dalam hal ini, terdapat node node sebelum dan setelah kami saat ini node. Semua kita perlu lakukan adalah menghubungkan ke node sebelumnya node node setelah kami saat ini. Kami telah menetapkan sementara kami sama dengan sebelumnya node dan mengatur Berikut pointer ke node setelah kami saat ini (jenazah). Setelah tersambung, kita dapat dengan mudah menghapus pointer kita saat ini! Itu semua adalah untuk menghapus node!

Sebelum Keluar

Sebelum kita dapat keluar dari program kami, kami harus memastikan bahwa kita semua dialokasikan secara dinamis struktur atau node akan dihapus, kalau tidak kita akan memiliki memori leak! Untuk memperbaiki ini, kita dapat membangun sebuah rutin untuk mengalokasikan ada sisa-node. Mari kita ini otomatis dan tempat di kelas membakar sampah!
SLList:: ~ SLList ()
(Temp = ListPtr Kepala;
CurrentPtr = Kepala;

sementara (CurrentPtr! = NULL)
(CurrentPtr = CurrentPtr-> Selanjutnya;
menghapus temp;
temp = CurrentPtr;
)
)

Traverses ini melalui daftar de-mengalokasikan node bergerak bersama karena telah mencapai sampai akhir! That’s all there is to it!
CB BY:JUSTIN DELIENCI

SORTING

mengurutkan
Sintaks:
# include
void sort (iterator mulai, iterator akhir);
void sort (iterator mulai, akhir iterator, StrictWeakOrdering CMP);
Yang mengurutkan () algoritma jenis unsur-unsur dalam kisaran [start,end) naik ke dalam pesanan. Jika dua elemen yang sama, tidak ada jaminan agar apa yang mereka akan masuk
Jika lemah memesan ketat fungsi objek cmp yang diberikan, maka akan digunakan untuk membandingkan dua benda daripada <
Algoritma yang mengurutkan belakang () adalah algoritma introsort. mengurutkan () dijalankan di dalam O (N log (N)) waktu (rata-rata dan terburuk kasus) yang lebih cepat daripada jumlahnya banyak waktu tetapi lambat dibandingkan linear waktu.
Perlu diketahui bahwa mengurutkan () hanya akan bekerja dengan akses acak iterators. Sehingga Anda tidak dapat menggunakan sort () pada iterators dari "daftar" (link list). Sebaliknya, Anda harus menggunakan daftar sendiri mengurutkan metode ini untuk mengurutkan instead.
Sebagai contoh, kode berikut jenis yang vector dari integers naik ke dalam rangka:
Vector v;
v. push_back (23);
v. push_back (- 1);
v. push_back (9999);
v. push_back (0);
push_back ayat (4);

cout << "Sebelum sorting:";
for (unsigned int i = 0; i
cout <<< "";
)
cout <

Mengurutkan (ayat mulai (), ayat akhir ());

cout << "Setelah sorting:";
for (unsigned int i = 0; i
cout <<< "";
)
cout <
Bila berjalan, di atas kode ini akan menampilkan output:
Sebelum sorting: 23 -1 9999 0 4
Setelah penyortiran: -1 0 4 23 9999
Atau, kode berikut menggunakan sort () fungsi untuk mengurutkan array biasa dari integers, dan menampilkan output yang sama seperti sebelumnya contoh:
int array [] = (23, – 1, 9999, 0, 4);
unsigned int array_size = 5;

cout << "Sebelum sorting:";
for (unsigned int i = 0; i
cout <<< "";
)
cout <

Sort (array, array + array_size);

cout << "Setelah sorting:";
for (unsigned int i = 0; i
cout <<< "";
)
cout <
Ini contoh berikut ini menunjukkan cara menggunakan sort () dengan pengguna ditentukan perbandingan fungsi. Fungsi cmp didefinisikan untuk melakukan hal yang berlawanan dari b;
)

vector v;
for (int i = 0; i <10; i + +) (
push_back ayat (i);
)

cout << "Sebelum:";
for (int i = 0; i <10; i + +) (
cout <<< "";
)
cout <

Mengurutkan (ayat mulai (), akhir ayat (), CMP);

cout << "Setelah:";
for (int i = 0; i <10; i + +) (
cout <<< "";
)
cout <

SEARCHING

Searching adalah proses pencarian data dari sekumpulan data yang sudah ada. Pencarian data sering juga disebut dengan table look-up atau store and retrieval information. Hasil dari suatu pencarian dapat bernilai salah (tidak ketemu atau tidak sukses) atau benar (ketemu atau sukses). Untuk data yang tidak ketemu biasanya ada prosedur tersendiri untuk menambah atau menyisipkan data yang belum ada tersebut.
Pencarian biner merupakan salah satu cara atau metode untuk melaksanakan proses pencarian. Cara ini merupakan cara yang paling cepat di antara metode-metode yang lainnya. Metode pencarian biner dapat dijelaskan sebagai berikut. Pertama-tama data-data yang sduah ada harus diurutkan dahulu. Selanjuutnya data yang sudah diurutkan tadi disebut sebagai vektor. Kemudian vektor tadi dibagi menjadi dua subvektor yang memiliki jumlah elemen yang sama, kemudian data yang dicari dibandingkan dengan data terakhir dari subvektor pertama. Jika data tersebut lebih kecil maka berarti data kemungkinan ada di subvektor pertama, sehingga pencarian dapat dilakukan di subvektor pertama dengan terlebih dahulu membagi subvektor tadi menjadi dua subvektor. Jika lebih besar maka berarti data kemungkinan ada di subvektor kedua, sehingga pencarian dapat dilakukan di subvektor kedua dengan terlebih dahulu menbagi subvektor tadi menjadi dua subvektor.

Contoh program:

#include
#include

void main() {
int i, j, iMin;
int Tengah, ElmTengah, Tmp;
int n, dt;
int Posisi, Ketemu;
int Arr[50];

//Aplikasi dimulai
printf("Inputkan banyak data : ");
scanf("%i", &n);
//Input array
for(i = 0; i < n; i++) { //Perulangan untuk inputan array
printf("Masukan data ke %i : ", i + 1);
scanf("%i", &Arr[i]);
}
//Lakukan sorting ascending dengan metode bubble
for(i = 1; i < n; i++) { //Lakukan perulangan untuk akses array
for(j = 0; j Arr[j + 1]) { //Cocokkan data 1 dengan data yang
Tmp = Arr[j]; //Tampung array lama
Arr[j] = Arr[j + 1]; //Ganti yang lama dengan array baru
Arr[j + 1] = Tmp; //Array baru ditukar dengan yang lama
}
}
}

//Proses Pencarian
printf(“\nMasukan data yang dicari : “);
scanf(“%i”, &dt);
//Init Proses Pencarian
Ketemu = 0; //Data belum ditemukan
Tengah = (n / 2) + 1; //Cari titik tengah
ElmTengah = Arr[Tengah]; //Set elemen tengah
i = 0; //Set index = 0
//Proses dimulai
if(dt == ElmTengah) {
Ketemu = 1;
Posisi = Tengah;
} else {
if(dt < ElmTengah) {
i = 0;
while((Ketemu == 0 && i < Tengah) && Arr[i] <= dt) {
if(Arr[i] == dt) {
Ketemu = 1;
Posisi = i;
} else {
i = i + 1;
}
}
} else {
i = Tengah + 1;
while((Ketemu == 0 && i < n) && Arr[i] <= dt) {
if(Arr[i] == dt) {
Ketemu = 1;
Posisi = i;
} else {
i = i + 1;
}
}
}
}
//Tampilkan Hasil
if(Ketemu == 0) { //Jika data tidak ditemukan
printf("Data tidak ditemukan…\n");
} else { //Jika data ditemukan
printf("Setelah Pengurutan : \n");
for(i = 0; i < n; i++) { //Perulangan untuk tampilan array
printf("Elemen ke %i : %i\n", i + 1, Arr[i]);
}
printf("Data ditemukan pada Posisi %i \n", Posisi + 1);
}
getch(); //Tahan tampilan
}

SUMBER:GOOGLE

Halaman Berikutnya »



Ikuti

Get every new post delivered to your Inbox.