Ierarxik va tarmoqlanuvchi tuzilmalar
Tree (Daraxt) - bu ierarxik tuzilma bo'lib, ildiz (root) tugundan boshlanadi va har bir tugun farzandlarga ega bo'lishi mumkin. Binary Tree da har bir tugun maksimum 2 ta farzandga ega bo'ladi: chap va o'ng.
// TreeNode klassi
public class TreeNode
{
public int Data { get; set; }
public TreeNode Left { get; set; }
public TreeNode Right { get; set; }
public TreeNode(int data)
{
Data = data;
Left = null;
Right = null;
}
}
// Binary Tree yaratish
TreeNode root = new TreeNode(10);
root.Left = new TreeNode(5);
root.Right = new TreeNode(15);
root.Left.Left = new TreeNode(3);
root.Left.Right = new TreeNode(7);
/*
10
/ \
5 15
/ \
3 7
*/
// Preorder: Root → Left → Right
public void Preorder(TreeNode node)
{
if (node != null)
{
Console.Write(node.Data + " ");
Preorder(node.Left);
Preorder(node.Right);
}
}
// Inorder: Left → Root → Right
public void Inorder(TreeNode node)
{
if (node != null)
{
Inorder(node.Left);
Console.Write(node.Data + " ");
Inorder(node.Right);
}
}
// Postorder: Left → Right → Root
public void Postorder(TreeNode node)
{
if (node != null)
{
Postorder(node.Left);
Postorder(node.Right);
Console.Write(node.Data + " ");
}
}
// Daraxt balandligi
public int Height(TreeNode node)
{
if (node == null) return 0;
return Math.Max(Height(node.Left), Height(node.Right)) + 1;
}
Binary Search Tree (BST) - bu maxsus binary tree bo'lib, quyidagi xususiyatga ega: Har bir tugunning chap farzandlari undan kichik, o'ng farzandlari undan katta bo'ladi. Bu tezkor qidiruvni ta'minlaydi.
// BST ga element qo'shish
public TreeNode Insert(TreeNode root, int data)
{
if (root == null)
{
return new TreeNode(data);
}
if (data < root.Data)
{
root.Left = Insert(root.Left, data);
}
else if (data > root.Data)
{
root.Right = Insert(root.Right, data);
}
return root;
}
// Ishlatish
TreeNode root = null;
root = Insert(root, 50);
root = Insert(root, 30);
root = Insert(root, 70);
root = Insert(root, 20);
root = Insert(root, 40);
// BST da element qidirish - O(log n)
public bool Search(TreeNode node, int data)
{
if (node == null)
return false;
if (node.Data == data)
return true;
if (data < node.Data)
return Search(node.Left, data);
else
return Search(node.Right, data);
}
// Minimal element
public int FindMin(TreeNode node)
{
while (node.Left != null)
{
node = node.Left;
}
return node.Data;
}
// Maksimal element
public int FindMax(TreeNode node)
{
while (node.Right != null)
{
node = node.Right;
}
return node.Data;
}
// BST dan element o'chirish
public TreeNode Delete(TreeNode root, int data)
{
if (root == null) return root;
if (data < root.Data)
{
root.Left = Delete(root.Left, data);
}
else if (data > root.Data)
{
root.Right = Delete(root.Right, data);
}
else
{
// Case 1: Bola yo'q yoki bitta bola
if (root.Left == null)
return root.Right;
else if (root.Right == null)
return root.Left;
// Case 2: Ikki bola bor
root.Data = FindMin(root.Right);
root.Right = Delete(root.Right, root.Data);
}
return root;
}
Graf - bu tugunlar (vertices) va ular orasidagi qirralar (edges) to'plami. Murakkab munosabatlarni ifodalash uchun ishlatiladi. Yo'naltirilgan va yo'naltirilmagan graflar mavjud.
// Graf - Qo'shnilik Ro'yxati
public class Graph
{
private Dictionary<int, List<int>> adjList;
public Graph()
{
adjList = new Dictionary<int, List<int>>();
}
// Tugun qo'shish
public void AddVertex(int vertex)
{
if (!adjList.ContainsKey(vertex))
{
adjList[vertex] = new List<int>();
}
}
// Qirra qo'shish (yo'naltirilmagan)
public void AddEdge(int v1, int v2)
{
if (!adjList.ContainsKey(v1))
AddVertex(v1);
if (!adjList.ContainsKey(v2))
AddVertex(v2);
adjList[v1].Add(v2);
adjList[v2].Add(v1);
}
}
// BFS (Breadth-First Search)
public void BFS(int startVertex)
{
HashSet<int> visited = new HashSet<int>();
Queue<int> queue = new Queue<int>();
visited.Add(startVertex);
queue.Enqueue(startVertex);
Console.Write("BFS: ");
while (queue.Count > 0)
{
int vertex = queue.Dequeue();
Console.Write(vertex + " ");
foreach (int neighbor in adjList[vertex])
{
if (!visited.Contains(neighbor))
{
visited.Add(neighbor);
queue.Enqueue(neighbor);
}
}
}
Console.WriteLine();
}
// DFS (Depth-First Search)
public void DFS(int startVertex)
{
HashSet<int> visited = new HashSet<int>();
Console.Write("DFS: ");
DFSRecursive(startVertex, visited);
Console.WriteLine();
}
private void DFSRecursive(int vertex, HashSet<int> visited)
{
visited.Add(vertex);
Console.Write(vertex + " ");
foreach (int neighbor in adjList[vertex])
{
if (!visited.Contains(neighbor))
{
DFSRecursive(neighbor, visited);
}
}
}
Hash Table - bu kalit-qiymat juftliklarini saqlash uchun ishlatiladigan samarali tuzilma. Hash funksiyasi yordamida kalitdan indeks hisoblanadi. O'rtacha O(1) murakkablikda operatsiyalar bajariladi.
// Dictionary (Hash Table)
Dictionary<string, int> hashTable = new Dictionary<string, int>();
// Put - qo'shish - O(1)
hashTable["Ali"] = 25;
hashTable["Vali"] = 30;
hashTable.Add("Hasan", 28);
// Get - olish - O(1)
int age = hashTable["Ali"]; // 25
// TryGetValue - xavfsiz olish
if (hashTable.TryGetValue("Ali", out int value))
{
Console.WriteLine($"Ali: {value}");
}
// Contains - mavjudligini tekshirish
bool hasKey = hashTable.ContainsKey("Ali");
bool hasValue = hashTable.ContainsValue(25);
// Remove - o'chirish - O(1)
hashTable.Remove("Vali");
// Count
int count = hashTable.Count;
// Aylantirish
foreach (var kvp in hashTable)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
Heap - bu maxsus to'liq binary tree bo'lib, ustuvorlikli navbat uchun ishlatiladi. Max Heap da ota tugun farzandlaridan katta, Min Heap da esa kichik bo'ladi.
// Priority Queue (Heap asosida)
// .NET 6+ da
PriorityQueue<string, int> pq = new PriorityQueue<string, int>();
// Enqueue - qo'shish - O(log n)
pq.Enqueue("Task 1", 3); // priority: 3
pq.Enqueue("Task 2", 1); // priority: 1 (yuqori)
pq.Enqueue("Task 3", 5); // priority: 5
// Dequeue - eng yuqori ustuvorlikni olish - O(log n)
string task = pq.Dequeue(); // "Task 2" (1 eng yuqori)
// Peek - ko'rish - O(1)
string nextTask = pq.Peek();
// Count
int count = pq.Count;
// Custom Priority Queue
public class MaxHeap
{
private List<int> heap = new List<int>();
public void Insert(int value)
{
heap.Add(value);
HeapifyUp(heap.Count - 1);
}
public int ExtractMax()
{
int max = heap[0];
heap[0] = heap[heap.Count - 1];
heap.RemoveAt(heap.Count - 1);
HeapifyDown(0);
return max;
}
}