Bu yazımızda C++ programlama dilinde if else yapılarına değineceğiz. Fakat bu yolculuğa çıkmadan önce algoritma ve koşul ifadelerine değineceğiz.


Algoritma

Algoritma, bir sorunu çözmek veya belirlenmiş bir hedefe ulaşmak için izlenen yoldur. Amaca ulaşmak için bir başlangıcı olan ve bir sonu olan işlemler bütünüdür. Yataktan kalkıp işe gitmek için genç bir idareci tarafından takip edilen "kalk ve ışılda" algoritmasını düşünün.,

  1. Yataktan kalk
  2. Pijamalarını çıkar
  3. Duş al
  4. Giyin
  5. Kahvaltı yap
  6. İşe git
Bu akış, genç idareciyi kritik kararlar vermeye iyi bir şekilde hazırlar. Aynı adımları farklı sırada yaptığını düşünün:
  1. Yataktan kalk
  2. Pijamalarını çıkar
  3. Giyin
  4. Duş al
  5. Kahvaltı yap
  6. İşe git
Bu durumda genç idarecimiz işe sırılsıklam gidecektir. Bir bilgisayar programında ifadelerin hangi sırada yürütüleceğini belirlemeye program kontrolü denir.


Sözde Kod


Sözde kod algoritma geliştirmemize yardımcı olan yapay ve gayri resmi bir dildir. Günlük bir dile benzer: gerçek bir bilgisayar programlama dili olmamasına rağmen uygun ve kullanıcı dostudur.
Bu kodları bilgisayarda çalıştıramayız. Aksine, bir programı C++ gibi bir bilgisayar programlama dilinde yazmaya başlamadan önce programı "planlama" mıza yardımcı olur. Yukarıda örnek olarak bahsettiğimiz "kalk ve ışılda algoritması" sözde koda örnek olarak verilebilir. 

Başka bir örnek:
  1. Bir sayıyı oku
  2. İkinci sayıyı oku
  3. Üçüncü sayıyı oku
  4. İlk iki sayıdan büyük olanı bul
  5. Eğer sonuç değişkeni üçüncü sayıdan büyük ise sonuç değerini yazdır
  6. Değilse
  7. Üçüncü sayıyı yazdır


Koşul İfadeleri


Koşul ifadelerini yazarken farklı değerleri karşılaştırmak için ilişkisel(relational) operatörler, ilişkisel ifadeleri birleştirmek için ise mantıksal(logical) operatörler kullanılır. Operatörler ile ilgili yazımızı buradan inceleye bilirisiniz.



İf Seçim İfadesi


Programlama sürecinde, kimi zaman farklı koşullarda programın farklı çalışması gerekmektedir. Örneğin bir bankamatiği ele alalım. Banka kartınızı aldıktan sonra bankamatik size şifre soracaktır. Eğer şifrenizi yanlış girerseniz size uyarı verecektir. Eğer şifrenizi doğru girerseniz sizi hesabınıza yönlendirecektir. Bu tip koşula bağlı karar verme işlemi için kullanabileceğimiz komutlardan ilki if komutudur.


if koşulu önce koşul ifadesinin denenmesi ile başlar. Eğer koşul ifadesi true döndürülürse, if koşulundan hemen sonra gelen komut yürütülür. Eğer koşul ifadesi false döndürülürse, bu komut atlanır ve program kaldığı yerden devam eder.

if komut söz dizimi:

if(koşul)
    komut;

Örnek bir kod:
if( yas >= 18 )
    cout<<"Oy kullanabilirsiniz."<endl

cout<<"Iyi gunler"<<endl;

Bu örnekte eğer yaş 19 ise (yas >= 18) koşul ifadesi true döndürür ve "Oy kullanabilirsiniz." yazan komut çalışır. Daha sonra program normal akışına devam eder ve "Iyi gunler" mesajını yazar. Bu durumda çıktı:
 Oy kullanabilirsiniz.
Iyi gunler

Eğer yaş değeri 17 ise, koşul ifadesi false döndürür. İlk komut yürütülmez ve çıktımız:
Iyi gunler



İf Else Seçim İfadesi


Aşağıda if..else yapısının syntax bulunmaktadır:

if (test expression) {
    Body of if
}
else {
    Body of else
}


if...else yapısı, koşulu değerlendirir ve yalnızca koşul "true" olduğunda if'in gövdesini çalıştırır. Koşulun "false" olması durumunda else gövdesi çalışır.

if...else'in akış şeması aşağıdaki gibidir:

Örnek:

#include <iostream>
using namespace std;
 
int main() {
  int age = 17;
  if (age > 18) {
    cout << "The person is an adult ";
  } 
  else {
    cout << "The person is not an adult ";
  } 
  return 0;
}

Çıktı:
The person is not an adult

Yukarıdaki örnekte: age değişkeninin değeri 17. if koşulunun true olabilmesi için age değişkeninin değerinin 18'den büyük olamsı gerekmektedir. Fakat 18'den küçük olduğu için if koşulu sağlanamaz, bu nedenle kod, else yapısının içinde çalışır ve daha sonra program normal akışına devam eder.



if..else if..else İfadeleri


Aşağıda if...else if...else yapısının syntax bulunmaktadır:

if (test expression 1) {
    Body of if
}
else if (test expression 2) {
    Body of else-if
}
else {
    Body of else
}

if... else if... else ifadesinde önce if ifadesinin koşulunu kontrol eder ve if gövdesini yalnızca koşulu True olduğunda çalıştırır.
Aksi takdirde, else if deyiminin koşuluna geçer. else if koşulunun True olması durumunda, else if'in gövdesi yürütülür. Birden fazla else if ifadesi olabileceğini unutmayın.
Kısaca, tüm koşulların False dönmesi durumunda else gövdesi çalıştırılacaktır.

Aşağıda if..else if..else yapısının akış şeması bulunmaktadır:

Örnek:
#include <iostream>
using namespace std;
 
int main() {
  int age = 11;
  if (age >= 13 && age < 20) {
    cout << "Person is a teenager ";
  } 
  else if (age >= 0 && age < 13) {
    cout << "Person is a prepubescent ";
  } 
  else {
    cout << "Person is an adult ";
  } 
  return 0;
}
Çıktı:
Person is a prepubescent 

Bu örnekte, age değişkeninin değeri 11'dir. İlk if koşulunun sağlanabilmesi için, age değişkeninin değerinin 13'e eşit ya da büyük ve 20'den küçük olması gerekmektedir. Fakat age değişkeninin değeri 11'dir. Bu neden bu koşul sağlanamadığı için else if yapısının koşuluna bakılmaktadır. else if yapısının koşulunun sağlanabilmesi için, age değişkeninin değerinin 0'a eşit ya da büyük ve 13'den küçük olması gerekmektedir. age değişkeninin değeri bu aralıkta olduğundan dolayı bu koşul sağlanır ve "true" olur. Bu sayede else if yapısının içine girer konsola "Person is a prepubescent " yazısı yazılır. else yapısının içine girmeyecektir. Çünkü else if yapısının koşulu sağlandığında else yapısına girmez. Fakat else if yapısının koşulu sağlanmasaydı, o zaman else yapısının içine girecektir.



Örnekler


1) Girilen sayının id değişkeninden büyük olması ya da küçük olması ya da eşit olması koşullarını kontrol eder:

#include <iostream>

using namespace std;

int main(void)
{
  int id;

  cout << "Bir int değer giriniz: ";
  cin >> id;
  
  if (id == 21) cout << "Girdiğiniz sayı 21'dir!";
  if (id < 21) cout << "Girdiğiniz sayı 21'den küçüktür!";
  if (id > 21) cout << "Girdiğiniz sayı 21'den büyüktür!";

  return 0;
}
Çıktı:

Bir int değer giriniz: 20
Girdiğiniz sayı 21'den küçüktür!

2)

#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2;

  id1 = 21;
  id2 = 0;

  if (id1!=0) cout << "id1 değişken değeri 0'dan farklıdır!" << "\n";
  if (id2==0) cout << "id2 değişken değeri 0'a eşittir!" << "\n\n";

  if (id1) cout << "id1 değişken değeri 0'dan farklıdır!" << "\n";
  if (!id2) cout << "id2 değişken değeri 0'a eşittir!";

  return 0;
}

Çıktı:

id1 değişken değeri 0'dan farklıdır!
id2 değişken değeri 0'a eşittir!

3)
#include <iostream>

using namespace std;

int main(void)
{
  int id;

  cout << "8 * 9 = ? işleminin sonucunu giriniz: ";
  cin >> id;

  if (id == 72) cout << "Cevabınız doğrudur!";
  else cout << "Cevabınız yanlıştır!";

  return 0;
}

Çıktı:

8 * 9 = ? işleminin sonucunu giriniz: 70
Cevabınız yanlıştır!

4)
#include <iostream>

using namespace std;

int main(void)
{
  int id;

  cout << "Bir int değer giriniz: ";
  cin >> id;

  if(id%2) {
    cout << "Girdiğiniz sayı tek bir sayıdır: " << id << "\n";
    cout << "Sayının 3 katı: " << 3 * id;
  }
  else {
    cout << "Girdiğiniz sayı çift bir sayıdır: " << id << "\n";
    cout << "Sayının 2 katı: " << 2 * id;
  }

  return 0;
}

Çıktı:

Bir int değer giriniz: 35
Girdiğiniz sayı tek bir sayıdır: 35
Sayının 3 katı: 105


4)
#include <iostream>

using namespace std;

int main(void)
{
  int id;

  cout << "Bir int değer giriniz: ";
  cin >> id;

  if(id > 100) { // 1
     cout << "Girilen sayı 100'den büyüktür!" << "\n"; // 2
     if(id % 2 == 0) { // 3
        cout << "Girilen sayı çift bir sayıdır!" << "\n"; // 4
        if (id<=150) cout << "Girilen sayı 100-150 arasındadır!"; // 5
        else cout << "Girilen sayı 150'den büyüktür!"; // 6
     }
     else cout << "Girilen sayı tek bir sayıdır!"; // 7
  }
  else { // 8
     if(id == 100) cout << "Girilen sayı 100'dür!"; // 9
     else cout << "Girilen sayı 100'den küçüktür!"; // 10
  }

  return 0;
}

Çıktı:

Bir int değer giriniz: 398
Girilen sayı 100'den büyüktür!
Girilen sayı çift bir sayıdır!
Girilen sayı 150'den büyüktür!





















Kaynak

https://learn.microsoft.com/en-us/cpp/cpp/if-else-statement-cpp?view=msvc-170
https://www.shiksha.com/online-courses/articles/cpp-if-else-statement/#s2
https://www.programiz.com/cpp-programming/if-else
https://www.bilgigunlugum.net/prog/cppprog/cpp_if
https://www.javatpoint.com/cpp-if-else

Bu yazımızda operatörlere değineceğiz. Operatörler değişkenler ve değerler üzerinde işlem yapmak için kullanılırlar. Aşağıda değineceğimiz operatörler belirtilmiştir:

  • İlişkisel operatörler
  • Mantıksal operatörler
  • Aritmetik operatörle
  • Bitsel operatörler

İlişkisel Operatörler

Koşul ifadelerini yazarken farklı değerleri karşılaştırmak için ilişkisel operatörler, ilişkisel ifadeleri birleştirmek için ise mantıksal operatörler kullanılır. Aşağıdaki tabloda ilişkisel operatörler listelenmektedir.

İlişkisel Operatörler


İlişkisel operatörlerle yazdığımız ifadelerin sonucu, bool değeri olan true veya false olacaktır. Örneğin aşağıdaki koşul ifadesi "x değeri y değerinden büyüktür" önermesini ifade ederi. Bu önerme doğru ise true, yanlış ise false değerini döndürür.

 x > y

== operatörünü atama operatörü (=) ile karıştırmamak gerekir. == operatörü eşitlik kontrolü yapar. = operatörü ise sağdaki değişkeni veya değeri soldaki değişkene atar. Örneğin:

x == 5 // x değişkeni 5'e eşit ise true, değilse false döndürür
x = 5; //x değişkenine 5 değeri atanır

Örnek1:

#include <iostream>
using namespace std;
int main() {
   int x = 5;
   if(x == 5){
       cout<<"x = "<< x;
   }
   else{
       cout<<" x degeri 5 degil";
   }
    return 0;
}

Bu örnekte x değişkeni 5'e eşit olduğu için if yapısı true dönecektir. Bundan dolayı çıktı:

x = 5

Fakat x, 5'den farklı bir sayı olsaydı if koşulu FALSE dönecekti ve else yapısının içine girecekti. Mesela;

#include <iostream>
using namespace std;
int main() {
   int x = 7;
   if(x == 5){
       cout<<"x = "<< x;
   }
   else{
       cout<<" x degeri 5 degil";
   }
    return 0;
}

Bu örnek de x'in değeri 7'dir. Bu nedenle if koşulu sağlanmaz ve else yapısının içine girer ve çıktı:

x degeri 5 degil

Örnek2

#include <iostream>

using namespace std;

int main() {
   int x = 7;
   int y = 10;

   if(x > y){
       cout<<"x, y'den buyuk";
   }
   else{
       cout<<"y, x'den buyuk ";
   }
    return 0;
}

Bu örnekte iki tane değişken vardır ve bu değişkenleri birbiri ile karşılaştırıyoruz. x değişkeninin değeri 7 olarak atanmıştır. Aynı şekilde y değişkeninin değeri de 10 olarak atanmıştır. if yapısında x değişkeninin ye değişkeninden büyük bulması durumda TRUE döndürecektir ve çıktı olarak x, y'den buyuk. Fakat bizim örneğimizde x değişkeni, y değişkeninden küçük olduğu için if koşulu FALSE dönecektir ve else yapısının içine girecektir ve program çıktısı aşağıdaki gibi olacaktır:

y, x'den buyuk 


Mantıksal Operatörler

İlişkisel ifadeleri birleştirmek için mantıksal operatörleri kullanmamız gerektiğine değinmiştik. Birleştirme işlemi için kullandığımız mantıksal operatörler aşağıda belirtilmiştir.

Mantıksal Operatörler

Örnek1

#include <iostream>

using namespace std;

int main() {
   int x = 7;
   int y = 10;

   if(x == 7 && y == 10){
       cout<<"x = "<<x<<",y = "<<y;
   }
   else{
       cout<<"x != "<<x<<",y != "<<y;
   }
    return 0;
}

Bu örnekte x değişkeninin ve y değişkenin de koşulu sağlaması halinde if koşulu TRUE olacaktır. Eğer bu değişkenlerden biri koşulu sağlamaz ise FALSE olacaktır ve else yapısının içerisine girecektir
Çıktı:

x = 7,y = 10

Örnek2

#include <iostream>

using namespace std;

int main() {
   int x = 10;
   int y = 10;

   if(x == 7 || y == 10){
       cout<<"x = "<<x<<",y = "<<y;
   }
   else{
       cout<<"x != "<<x<<",y != "<<y;
   }
    return 0;
}

Bu örnekte, x değişkeninin değeri 10'dur. if yapısında x==7 koşulu doğru değildir. Fakat y==10 koşulu sağlanmaktadır ve kullanılan operatör "veya( || )" operatörü olduğu için içlerinden birinin koşulu sağlaması yeterli olacaktır. Bu nedenle if koşulu TRUE olur. FALSE olabilmesi için iki koşulunda sağlanmaması gerekir. 
Çıktı:

x = 10,y = 10

Aritmetik Operatörler

Aritmetik operatörler toplama, çıkarma, çarpma, bölme, mod alma gibi matematiksel işlemleri yapmamızı sağlayan operatörlerdir.

Aritmetik Operatörler



Örnek

#include <iostream>

using namespace std;

int main() {
   int x = 15;
   int y = 5;
   
   cout<<"x+y = "<< x+y<<endl;
   cout<<"x-y = "<< x-y<<endl;
   cout<<"x*y = "<< x*y<<endl;
   cout<<"x/y = "<< x/y<<endl;
   cout<<"x%y = "<< x%y<<endl;

    return 0;
}

Çıktı:

x+y = 20
x-y = 10
x*y = 75
x/y = 3
x%y = 0

x değişkeni, y değişkeninin katı olduğu için mod değeri 0'dır.

Bitsel Operatörler

Bitsel operatörler bitler üzerinde çalışır ve bit bit işlemler gerçekleştirmemiz gerektiğinde kullanırız.

Bitsel Operatörler


Örnek

#include <iostream>

using namespace std;

int main() {
   int x = 3;
   int y = 5;
   int z = 2;
   
   cout<<"x&y = "<< (x&y)<<endl;
   cout<<"x|y = "<< (x|y)<<endl;
   cout<<"x^y = "<< (x^y)<<endl;
   cout<<"x<<z = "<< (x<<z)<<endl;
   cout<<"x>>z = "<< (y>>z)<<endl;
   
    return 0;
}

Çıktı:

x&y = 1
x|y = 7
x^y = 6
x<<z = 12
x>>z = 1


Kaynaklar:

https://turkmuhendis.net/algoritma/islemler/
https://merttopuz.com/yazilim/cpp/cpp-operatorler
https://www.w3schools.com/cpp/cpp_operators.asp
https://www.tutorialspoint.com/cplusplus/cpp_operators.htm
https://firateski.com/ders-3-c-operatorler
https://www.algoritmaornekleri.com/c-plus-plus/c-operatorler/#Bitsel_Operatorler
https://serdarkuzucu.com/bitwise-operatorler/


Stack(Yığın)

Stack(yığın), aynı türden verilerin bulunduğu lineer(doğrusal) bir veri yapısıdır. Stack, Son Giren İlk Çıkar (Last In First Out - LIFO) şekilinde çalışır yani stack'a eklenen son ögenin ilk kaldırıldığı anlamına gelir. 



Last In First Out (LIFO):

Bu strateji, son eklenen ögenin ilk çıkarılacağını belirtir. Gerçek hayattan bir örnek olarak üst üste yerleştirilmiş tabak yığını düşünülebilir. En son koyduğumuz tabak en üsttedir ve en üstteki tabağı çıkardığımızda, en son konan tabak ilk çıkar diyebiliriz.


Eğer en alttaki tabağı istiorsak, önce üstteki tüm tabakları çıkartmamız gerekir. Stack(yığın) veri yapısı tam olark böyle çalışır.

Stack LIFO Prensibi

Programlama terimlerinde, bir öğeyi stack'ın üstüne koymaya push, bir öğeyi kaldırmaya ise pop denir.


Görselde, 3. öğe en sonda kalmasına rağmen, ilk olarak kaldırılmıştır.

Stack'ın Temel İşlemleri

Bir stack üzerinde farklı eylemler gerçekleştirmemizi sağlayan bazı temel işlemler vardır.

push: Bir stack'ın üstüne bir eğe ekler
pop: Bir stack'ın tepesinden bir öğeyi kaldırma
IsEmpty: Stack'ın boş olup olmadığını kontrol eder
IsFull: Stack'ın dolu olup olmadığını kontrol eder
peek: Üst öğenin değerini kaldırmadan alma

Stack Türleri

Register Stack(Kayıt Yığını)

Bu tür bir stack aynı zamanda bellek biriminde bulunan bir bellek öğesidir ve yalnızca az miktarda veriyi işleyebilir. Register stack'nın boyutu belleğe kıyasla çok küçük olduğundan, register stack'nın yüksekliği her zaman sınırlıdır. 

Memory Stack(Bellek Yığını)

Bu tür bir stack, büyük miktarda bellek verisini işleyebilir. Memort stack'nın yüksekliği, büyük miktarda bellek verisi kapşadığından esnektir.

Stack Uygulaması

1. Dizi Kullanarak

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

// stack'ı temsil edecek bir struct
struct Stack{
int top;
unsigned capacity;
int* array;
};

// verilen kapasitede bir stack oluşturma. Stack boyutu 0 olarak başlatılır
struct Stack* createStack(unsigned capacity){
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (int*) malloc(stack->capacity*sizeof(int));
return stack;
}

// top son indekse eşit olduğında stack dolu
int isFull(struct Stack* stack){
return stack->top == stack->capacity - 1;
}

// top -1'e eşit olduğunda stack boştur
int isEmpty(struct Stack* stack){
return stack->top == -1;
}

// Stack'a bir öğe ekleme, top'u 1 artırır
void push(struct Stack* stack,int item){
if(isFull(stack)) return;
stack->array[++stack->top] = item;
printf("%d stack'a eklendi\n",item);
}

// Stack'tan bir öğe kaldırma, top 1 azaltılır.
int pop(struct Stack* stack){
if (isEmpty(stack)) return INT_MIN;
return stack->array[stack->top--];
}

// üst kısmı çıkarmadan stack'ı döndürme
int peek(struct Stack* stack){
if(isEmpty(stack)) return INT_MIN;
return stack->array[stack->top];
}

int main(){
struct Stack* stack = createStack(5);
push(stack,10);
push(stack,40);
push(stack,20);
push(stack,50);

printf("%d stack'tan kaldirildi\n",pop(stack));
return 0;
}
Çıktı:


Dizi Kullanmanın Avantajları:

  • Uygulaması kolay.

Dizi Kullanmanın Dezavantajları:

  • Dinamik değildir, yani çalışma zamanında ihtiyaca göre büyüyüp küçülmez.
  • Stack'ın toplam boyutu önceden tanımlanır.

2. Linked List Kullanarak

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

// stack'ı temsil edecek bir struct
struct StackNode{
int data;
struct StackNode* next;
};

struct StackNode* newNode(int data){
struct StackNode* stackNode = (struct StackNode*) malloc(sizeof(struct StackNode));
stackNode->data = data;
stackNode->next = NULL;
return stackNode;
}

int isEmpty(struct StackNode* root){
return !root;
}

void push(struct StackNode** root, int data){
struct StackNode* stackNode = newNode(data);
stackNode->next = *root;
*root = stackNode;
printf("%d stack'a eklendi\n",data);
}

int pop(struct StackNode** root){
if(isEmpty(*root)) return INT_MIN;
struct StackNode* temp = *root;
*root = (*root)->next;
int popped = temp->data;
free(temp);

return popped;
}

int peek(struct StackNode* root){
if(isEmpty(root)) return INT_MIN;
return root->data;
}

int main(){
struct StackNode* root = NULL;

push(&root,10);
push(&root,40);
push(&root,20);
push(&root,50);

printf("%d stack'tan kaldirildi\n",pop(&root));
printf("En ustteki eleman %d\n", peek(root));

return 0;
}
Çıktı:



Linked List Kullanmanın Avantajları:

  • Dinamiktir, yani çalışma zamanındaki ihtiyaçlara göre büyüyebilir ve küçülebilir.


Linked List Kullanmanın Dezavantajları:

  • Pointer'ların dahil olması nedeniyle ekstra bellek gerektirir.
  • Stack içinde rastgele erişim mümkün değildir.


Kaynaklar:
https://www.geeksforgeeks.org/introduction-to-stack-data-structure-and-algorithm-tutorials/
https://www.digitalocean.com/community/tutorials/stack-in-c
https://www.programiz.com/dsa/stack
https://www.tutorialspoint.com/data_structures_algorithms/stack_program_in_c.htm
 EN:
This article, we converted a 2D array to a 1D array in the c programming language. We did this using a for loop.

TR:
Bu yazımızda, c programlama dilinde 2D diziyi 1D diziye dönüştürdük. Bu işlemi for döngüsü kullanarak gerçekleştirdik.
#include <stdio.h>
#define m 3
#define n 4
int main() {
int arr1d[m*n];
int arr[m][n]={{1,3,4,6},
{4,7,8,9},
{3,5,8,1}};
printf("2D arry:\n");
for(int i =0;i<m;i++){
for(int j = 0; j<n; j++){
printf("%d ",arr[i][j]);
}
printf("\n");
}
printf("\n");
printf("1D arry:\n");
for(int i =0;i<m;i++){
for(int j = 0; j<n; j++){
arr1d[i*n+j]=arr[i][j];
}
}
for(int i = 0; i<m*n; i++){
printf("%d ",arr1d[i]);
}
return 0;
}

 Linked List Node Silme

Önceki yazılarımızda linked list ve linked list'te düğüm ekleme konularına değindik. Bu yazımızın konusu da linked list'ten node(düğüm) silme olacaktır.

Linked list'den düğüm silmek için aşağıdaki adımları takip edeceğiz:

  • Silinecek düğümden önceki düğümü bulun
  • Önceki düğümün next'ini değiştirin
  • Silinecek düğüm için free fonksiyonu ile belleği boşalt
Linked list'in her düğümü(node) malloc() kullanılarak dinamik olarak tahsis edildiğinden, silinecek olan düğüm için ayrılan belleği boşaltmak için free() fonksiyonu kullanılır.

Kod:

#include <stdio.h>
#include <stdlib.h>

// linked list düğümü
struct Node{
int data;
struct Node* next;
};

// linked list düğüm ekleme
void push(struct Node** head_ref,int new_data){
struct Node* new_node = (struct Node*) malloc(sizeof (struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}

// linked list düğüm silme
void deleteNode(struct Node** head_ref,int key){
struct Node *temp = *head_ref,*prev;
// Eğer ilk düğüm silinecek olan key'i tutuyorsa
if(temp != NULL && temp->data == key){
*head_ref = temp->next;
free(temp);
return;
}
// silinecek olan düğüm aranır
while (temp != NULL && temp->data != key){
prev=temp;
temp=temp->next;
}
// Eğer linked list'de key yoksa
if (temp == NULL){
return;
}
// düğümün linked list'teki bağlantısını kaldır
prev->next = temp->next;
free(temp); // free memory
}

void printList(struct Node* node){
while (node!=NULL){
printf("%d ",node->data);
node = node->next;
}
}
int main() {
// boş linked list başlatılır
struct Node* head = NULL;
//linked list'e düğüm eklenir
push(&head,3);
push(&head,6);
push(&head,4);
push(&head,2);
printf("Linked list:\n ");
printList(head);
// linked list'ten düğüm silinir
deleteNode(&head,4);
printf("\n4 silindikten sonra linked list: \n");
printList(head);
return 0;
}
Çıktı:
Linked list:
 2 4 6 3
4 silindikten sonra linked list:
2 6 3


C programlama ile ilgili olan diğer konulara aşağıdaki linkten ulaşabilirsiniz:

Kaynaklar:
https://www.geeksforgeeks.org/c-program-for-deleting-a-node-in-a-linked-list/
https://www.geeksforgeeks.org/linked-list-set-3-deleting-node/
https://www.programiz.com/dsa/linked-list-operations
https://www.log2base2.com/data-structures/linked-list/deleting-a-node-in-linked-list.html


 Bu örnekte C programlama dilinde, kullanıcıdan alınan sayının tek sayımı yoksa çift sayı mı olduğunu bulan programı yazdık:




#include <stdio.h>

void tekcift(int x){
    if(x%2==0){
        printf("Cift");
    }
    else
        printf("Tek");
}

int main() {
    int sayi;
    printf("Sayi giriniz: ");
    scanf("%d",&sayi);

    tekcift(sayi);

    return 0;
}

---------

#include <stdio.h>

int main() {
    int sayi;
    printf("Sayi giriniz: ");
    scanf("%d",&sayi);

    if(sayi%2==0){
        printf("Cift");
    }
    else
        printf("Tek");
    return 0;
}

Linked List Node Ekleme

 Bir önceki yazımızda linked list oluşturmayı öğrendik. Bu yazıda linked list'e node(düğüm) ekleme işlemine değineceğiz. 

Bir linked list'e düğm eklemenin 3 yöntemi vardır:

  • Linked List'in başına
  • Linked List'in sonuna
  • Linked List'de belirli bir düğümden sonra 

1. Linked List'in Başına Node (düğüm) Ekleme


Eklenen yeni düğüm linked list'in başına eklenir ve yeni eklenen düğüm linked list'in head(başı) olur. Örneğin linked list'in elemanları 1, 2, 3 vardır. Bu linked list'in başına 0'ı eklersek; 0, 1, 2, 3 olur. Liste'nin başına düğüm ekleyen fonksiyon push() olarak adlandıralım. push() fonksiyonu parametre olarak linked list'in head(baş) pointer'ını ve yeni düğüm değerini almalıdır. Çünkü, push() fonksiyonu yeni düğümü head ile değiştirmelidir.


#include <stdio.h>
#include <stdlib.h>
// bir linked list düğümü
struct Node{
int data;
struct Node* next;
};

// bu fonksiyon, verilen düğümden başlayarak linked list'in içeriğini yazdırır
void printList(struct Node* n){
while(n != NULL){
printf(" %d",n->data);
n = n->next;
}
}

void push(struct Node** head_ref,int new_data){
// yeni düğümü allocade etmek
struct Node* new_node = (struct Node*) malloc(sizeof (struct Node));
// yeni değeri al
new_node->data = new_data;
// yeni düğümü head yapmak
new_node->next = (*head_ref);
// yeni düğüme point etmek için head;
(*head_ref) = new_node;
}

int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;

// yığında 3 düğüm ayırmak
head = (struct Node*) malloc(sizeof (struct Node));
second = (struct Node*) malloc(sizeof (struct Node));
third =(struct Node*) malloc(sizeof (struct Node));

head->data = 1; // ilk düğüme değer atandı
head->next =second; // ilk düğümü, ikinci düğüme bağladık

second->data = 2; // ikinci düğüme değer atandı
second->next = third; // ikinci düğümü, üçüncü düğüme bağladık

third->data =3; // üçüncü düğüme değer atandı
third->next = NULL;

// fonksiyonu çağıralım
push(&head,0);
printList(head);

return 0;
}

Çıktı:

0 1 2 3

2. Linked List'de Belirli Bir Node(düğüm) Sonra Node(düğüm) Ekleme


Bize bir düğüm için pointer verilir ve yeni düğüm, verilen düğümden sonra eklenir. Örneğin linked list'in elemanları 1, 2, 3 vardır. Linked list'te 2'den sonra 5 değerini ekleriz ve sonuç 1, 2, 5, 3 olur. Belirli bir düğümden sonra düğüm eklemek için:

  • İlk olarak verilen düğümün NULL olup olmadığı kontrol edilir
  • Yeni düğüm atanır
  • Veriler yeni düğüme atanır
  • Yeni düğümün next'ini sonraki düğüme point etmelidir. Önceki düğümün nexti'i yeni düğüme point etmelidir.


#include <stdio.h>
#include <stdlib.h>
// bir linked list düğümü
struct Node{
int data;
struct Node* next;
};

// bu fonksiyon, verilen düğümden başlayarak linked list'in içeriğini yazdırır
void printList(struct Node* n){
while(n != NULL){
printf(" %d",n->data);
n = n->next;
}
}

// bir düğümden sonra düğüm ekleme
void insertAfter(struct Node* prev_node, int new_data){
// verilen düğüm kontrol edilir
if(prev_node == NULL){
printf("Verilen node NULL olamaz");
return;
}
// yeni düğüm allocate edilir
struct Node* new_node = (struct Node*) malloc(sizeof (struct Node));
// yeni değer alınır
new_node->data=new_data;
// yeni düğümün next'i, önceki düğümün next'i yapılır
new_node->next = prev_node->next;
// önceli düğümün next'i, yeni düğüm yapılır
prev_node->next= new_node;
}
int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;

// yığında 3 düğüm ayırmak
head = (struct Node*) malloc(sizeof (struct Node));
second = (struct Node*) malloc(sizeof (struct Node));
third =(struct Node*) malloc(sizeof (struct Node));

head->data = 1; // ilk düğüme değer atandı
head->next =second; // ilk düğümü, ikinci düğüme bağladık

second->data = 2; // ikinci düğüme değer atandı
second->next = third; // ikinci düğümü, üçüncü düğüme bağladık

third->data =3; // üçüncü düğüme değer atandı
third->next = NULL;

// fonksiyonu çağıralım
insertAfter(head->next,5);
printList(head);

return 0;
}

Çıktı:

 1 2 5 3

3. Linked List'in Sonuna Node Ekleme


Yeni düğüm, linked list'in sonuna eklenir. Örneğin linked list'in elemanları 1, 2, 3 vardır. Bu linked list'i sonuna 4 ekleriz ve sonuç 1, 2, 3, 4 olur.



#include <stdio.h>
#include <stdlib.h>
// bir linked list düğümü
struct Node{
int data;
struct Node* next;
};

// bu fonksiyon, verilen düğümden başlayarak linked list'in içeriğini yazdırır
void printList(struct Node* n){
while(n != NULL){
printf(" %d",n->data);
n = n->next;
}
}
// sona düğüm eklemek
void append(struct Node** head_ref, int new_data){
// yeni düğüm allocate edilir
struct Node* new_node = (struct Node*) malloc(sizeof (struct Node));
struct Node *last = *head_ref;

// yeni değer alınır
new_node->data = new_data;
// bu düğüm son düğüm olduğu için, next'i NULL yapılır
new_node->next = NULL;
// Eğer linked list boş ise yeni düğüm head yapılır
if(*head_ref == NULL){
*head_ref = new_node;
return;
}
// Linked list boş değilse son düğüme geçiş yapılır
while (last->next != NULL){
last = last->next;
}
// son düğümün next'i yeni düğüm yapılır
last->next = new_node;
return;
}

int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;

// yığında 3 düğüm ayırmak
head = (struct Node*) malloc(sizeof (struct Node));
second = (struct Node*) malloc(sizeof (struct Node));
third =(struct Node*) malloc(sizeof (struct Node));

head->data = 1; // ilk düğüme değer atandı
head->next =second; // ilk düğümü, ikinci düğüme bağladık

second->data = 2; // ikinci düğüme değer atandı
second->next = third; // ikinci düğümü, üçüncü düğüme bağladık

third->data =3; // üçüncü düğüme değer atandı
third->next = NULL;

// fonksiyonu çağıralım
append(&head,4);
printList(head);

return 0;
}

Çıktı:
 1 2 3 4



C programlama ile ilgili olan diğer konulara aşağıdaki linkten ulaşabilirsiniz:

Kaynaklar
https://www.codesdope.com/blog/article/inserting-a-new-node-in-a-linked-list-in-c/
https://www.geeksforgeeks.org/linked-list-set-2-inserting-a-node/
https://www.programiz.com/dsa/linked-list-operations