મુખ્ય સામગ્રી પર જાઓ
  1. સંસાધનો/
  2. અભ્યાસ સામગ્રી/
  3. ઇન્ફોર્મેશન ટેકનોલોજી એન્જિનિયરિંગ/
  4. આઈટી સેમેસ્ટર 3/
  5. ડેટા સ્ટ્રક્ચર વિથ પાયથોન (4331601)/

ડેટા સ્ટ્રક્ચર વિથ પાયથોન (4331601) - શિયાળા 2023 સોલ્યુશન

·
અભ્યાસ-સામગ્રી સોલ્યુશન ડેટા-સ્ટ્રક્ચર પાયથોન 4331601 2023 શિયાળા
મિલવ ડબગર
લેખક
મિલવ ડબગર
ઇલેક્ટ્રિકલ અને ઇલેક્ટ્રોનિક મેન્યુફેક્ચરિંગ ઉદ્યોગમાં અનુભવી લેક્ચરર. એમ્બેડેડ સિસ્ટમ્સ, ઈમેજ પ્રોસેસિંગ, ડેટા સાયન્સ, મેટલેબ, પાયથન, STM32માં કુશળ. એલ.ડી. કોલેજ ઓફ એન્જિનિયરિંગ - અમદાવાદથી કમ્યુનિકેશન સિસ્ટમ્સ એન્જિનિયરિંગમાં માસ્ટર્સ ડિગ્રી ધરાવતા મજબૂત શિક્ષણ વ્યાવસાયિક.
અનુક્રમણિકા

પ્રશ્ન 1(a) [3 ગુણ]
#

Time Complexity માટે best case, worst case અને average case વ્યાખ્યાયિત કરો.

જવાબ:

ટેબલ: Time Complexity Cases

કેસનો પ્રકારવ્યાખ્યાઉદાહરણ
Best Caseએલ્ગોરિધમ execution માટે લઘુત્તમ સમયLinear search માં એલિમેન્ટ પહેલી પોઝિશન પર મળે
Worst Caseએલ્ગોરિધમ execution માટે મહત્તમ સમયLinear search માં એલિમેન્ટ છેલ્લી પોઝિશન પર મળે
Average Caseસામાન્ય input scenarios માટે અપેક્ષિત સમયLinear search માં એલિમેન્ટ મધ્યમાં મળે
  • Best Case: આદર્શ input conditions સાથે એલ્ગોરિધમ optimal પ્રદર્શન આપે
  • Worst Case: પ્રતિકૂળ input સાથે એલ્ગોરિધમ મહત્તમ સમય લે
  • Average Case: બધા શક્ય inputs માં execution time ની ગાણિતિક અપેક્ષા

મેમરી ટ્રીક: “BWA - Best, Worst, Average”

પ્રશ્ન 1(b) [4 ગુણ]
#

OOP માં Class અને Object શું છે? યોગ્ય ઉદાહરણ આપો.

જવાબ:

ટેબલ: Class vs Object

પાસુંClassObject
વ્યાખ્યાObjects બનાવવા માટે blueprint/templateClass નું instance
મેમરીકોઈ મેમરી allocate નથી થતીબનાવવામાં આવે ત્યારે મેમરી allocate થાય
ઉદાહરણCar (template)my_car = Car()
# Class definition
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def display(self):
        print(f"Name: {self.name}, Age: {self.age}")

# Object creation
student1 = Student("John", 20)
student1.display()
  • Class: Attributes અને methods વ્યાખ્યાયિત કરતું template
  • Object: વાસ્તવિક values સાથેનું instance

મેમરી ટ્રીક: “Class = Cookie Cutter, Object = વાસ્તવિક Cookie”

પ્રશ્ન 1(c) [7 ગુણ]
#

Simple nested loop અને numpy module નો ઉપયોગ કરીને બે matrix multiplication માટે પ્રોગ્રામ લખો.

જવાબ:

# Method 1: Simple Nested Loop નો ઉપયોગ
def matrix_multiply_nested(A, B):
    rows_A, cols_A = len(A), len(A[0])
    rows_B, cols_B = len(B), len(B[0])
    
    # Result matrix initialize કરો
    result = [[0 for _ in range(cols_B)] for _ in range(rows_A)]
    
    # Matrix multiplication
    for i in range(rows_A):
        for j in range(cols_B):
            for k in range(cols_A):
                result[i][j] += A[i][k] * B[k][j]
    
    return result

# Method 2: NumPy નો ઉપયોગ
import numpy as np

def matrix_multiply_numpy(A, B):
    A_np = np.array(A)
    B_np = np.array(B)
    return np.dot(A_np, B_np)

# ઉદાહરણ
A = [[1, 2], [3, 4]]
B = [[5, 6], [7, 8]]

print("Nested Loop Result:", matrix_multiply_nested(A, B))
print("NumPy Result:", matrix_multiply_numpy(A, B))
  • Nested Loop: Row, column અને multiplication માટે ત્રણ loops
  • NumPy: કાર્યક્ષમ multiplication માટે built-in dot() function

મેમરી ટ્રીક: “Row × Column = Result”

પ્રશ્ન 1(c) OR [7 ગુણ]
#

Array ના basic operations માટે એક પ્રોગ્રામ લખો.

જવાબ:

import array

# Array બનાવો
arr = array.array('i', [1, 2, 3, 4, 5])

def array_operations():
    print("મૂળ array:", arr)
    
    # Element insert કરો
    arr.insert(2, 10)
    print("insert(2, 10) પછી:", arr)
    
    # Element append કરો
    arr.append(6)
    print("append(6) પછી:", arr)
    
    # Element remove કરો
    arr.remove(10)
    print("remove(10) પછી:", arr)
    
    # Element pop કરો
    popped = arr.pop()
    print(f"Pop કરેલું element: {popped}, Array: {arr}")
    
    # Element શોધો
    index = arr.index(3)
    print(f"3 નું index: {index}")
    
    # Occurrences ગણો
    count = arr.count(2)
    print(f"2 નું count: {count}")

array_operations()

ટેબલ: Array Operations

OperationMethodવર્ણન
Insertinsert(index, value)ચોક્કસ position પર element ઉમેરવું
Appendappend(value)છેડે element ઉમેરવું
Removeremove(value)પહેલું occurrence દૂર કરવું
Poppop()છેલ્લું element દૂર કરીને return કરવું

મેમરી ટ્રીક: “IARP - Insert, Append, Remove, Pop”

પ્રશ્ન 2(a) [3 ગુણ]
#

Big ‘O’ Notation સમજાવો.

જવાબ:

ટેબલ: Big O Complexity

Notationનામઉદાહરણ
O(1)ConstantArray access
O(n)LinearLinear search
O(n²)QuadraticBubble sort
O(log n)LogarithmicBinary search
  • Big O: એલ્ગોરિધમની time complexity ની upper bound વર્ણવે છે
  • હેતુ: વિવિધ એલ્ગોરિધમની કાર્યક્ષમતાની તુલના કરવી
  • ધ્યાન: Worst-case scenario analysis પર

મેમરી ટ્રીક: “Big O = વૃદ્ધિના Big Order”

પ્રશ્ન 2(b) [4 ગુણ]
#

Class method અને static method વચ્ચે તફાવત લખી સમજાવો.

જવાબ:

ટેબલ: Method Types Comparison

પાસુંClass MethodStatic Method
Decorator@classmethod@staticmethod
પહેલું Parametercls (class reference)કોઈ ખાસ parameter નહીં
AccessClass variables ને access કરી શકેClass/instance variables ને access કરી શકતું નથી
ઉપયોગAlternative constructorsUtility functions
class MyClass:
    class_var = "હું class variable છું"
    
    @classmethod
    def class_method(cls):
        return f"Class method accessing: {cls.class_var}"
    
    @staticmethod
    def static_method():
        return "Static method - કોઈ class access નથી"

# ઉપયોગ
print(MyClass.class_method())
print(MyClass.static_method())

મેમરી ટ્રીક: “Class method માં CLS છે, Static method STandalone છે”

પ્રશ્ન 2(c) [7 ગુણ]
#

Public અને private type derivation નો ઉપયોગ કરીને single level inheritance માટે class બનાવો.

જવાબ:

# Base class
class Vehicle:
    def __init__(self, brand, model):
        self.brand = brand          # Public attribute
        self._model = model         # Protected attribute
        self.__year = 2023          # Private attribute
    
    def start_engine(self):
        return f"{self.brand} engine શરૂ થયું"
    
    def _display_model(self):       # Protected method
        return f"Model: {self._model}"
    
    def __private_method(self):     # Private method
        return f"Year: {self.__year}"

# Derived class (Single level inheritance)
class Car(Vehicle):
    def __init__(self, brand, model, doors):
        super().__init__(brand, model)
        self.doors = doors
    
    def car_info(self):
        # Public અને protected members ને access કરી શકે
        return f"Car: {self.brand}, {self._display_model()}, Doors: {self.doors}"
    
    def demonstrate_access(self):
        print("Public access:", self.brand)
        print("Protected access:", self._model)
        # print("Private access:", self.__year)  # આ error આપશે

# ઉપયોગ
my_car = Car("Toyota", "Camry", 4)
print(my_car.car_info())
print(my_car.start_engine())
my_car.demonstrate_access()
  • Public: બધે accessible (brand)
  • Protected: Class અને subclasses માં accessible (_model)
  • Private: માત્ર સમાન class માં accessible (__year)

મેમરી ટ્રીક: “Public = બધા, Protected = કુટુંબ, Private = વ્યક્તિગત”

પ્રશ્ન 2(a) OR [3 ગુણ]
#

Constructor ને ઉદાહરણ સાથે સમજાવો.

જવાબ:

ટેબલ: Constructor Types

પ્રકારMethodહેતુ
Default__init__(self)Default values સાથે initialize
Parameterized__init__(self, params)Custom values સાથે initialize
class Student:
    def __init__(self, name="અજ્ઞાત", age=18):  # Constructor
        self.name = name
        self.age = age
        print(f"Student {name} બનાવ્યો")
    
    def display(self):
        print(f"નામ: {self.name}, ઉંમર: {self.age}")

# Object creation automatically constructor ને call કરે છે
s1 = Student("Alice", 20)
s2 = Student()  # Default values ઉપયોગ કરે
  • Constructor: Object બનાવવામાં આવે ત્યારે call થતી special method
  • હેતુ: Object attributes ને initialize કરવા
  • Automatic: Object creation દરમિયાન automatically call થાય

મેમરી ટ્રીક: “Constructor = Object નું જન્મ પ્રમાણપત્ર”

પ્રશ્ન 2(b) OR [4 ગુણ]
#

Polymorphism દર્શાવવા માટે એક પ્રોગ્રામ લખો.

જવાબ:

# Base class
class Animal:
    def make_sound(self):
        pass

# Derived classes
class Dog(Animal):
    def make_sound(self):
        return "ભોંભોં!"

class Cat(Animal):
    def make_sound(self):
        return "મિયાઉં!"

class Cow(Animal):
    def make_sound(self):
        return "હંભા!"

# Polymorphism demonstration
def animal_sound(animal):
    return animal.make_sound()

# Objects બનાવવા
animals = [Dog(), Cat(), Cow()]

# સમાન method call, અલગ behavior
for animal in animals:
    print(f"{animal.__class__.__name__}: {animal_sound(animal)}")

ટેબલ: Polymorphism ના ફાયદા

ફાયદોવર્ણન
લવચીકતાસમાન interface, અલગ implementations
જાળવણીનવા types ઉમેરવા સહેલા
Code Reuseવિવિધ objects માટે સામાન્ય interface

મેમરી ટ્રીક: “Poly = ઘણા, Morph = સ્વરૂપો”

પ્રશ્ન 2(c) OR [7 ગુણ]
#

Multiple અને hierarchical inheritance નો ઉપયોગ કરી પાયથોન પ્રોગ્રામ લખો.

જવાબ:

# Multiple Inheritance
class Teacher:
    def __init__(self, subject):
        self.subject = subject
    
    def teach(self):
        return f"{self.subject} શીખવાડવું"

class Researcher:
    def __init__(self, field):
        self.field = field
    
    def research(self):
        return f"{self.field} માં સંશોધન કરવું"

# Multiple inheritance
class Professor(Teacher, Researcher):
    def __init__(self, name, subject, field):
        self.name = name
        Teacher.__init__(self, subject)
        Researcher.__init__(self, field)
    
    def profile(self):
        return f"પ્રોફેસર {self.name}: {self.teach()} અને {self.research()}"

# Hierarchical Inheritance
class Vehicle:
    def __init__(self, brand):
        self.brand = brand
    
    def start(self):
        return f"{self.brand} શરૂ થયું"

class Car(Vehicle):
    def drive(self):
        return f"{self.brand} કાર ચાલે છે"

class Bike(Vehicle):
    def ride(self):
        return f"{self.brand} બાઇક ચાલે છે"

# ઉપયોગ
prof = Professor("સ્મિથ", "પાયથોન", "AI")
print(prof.profile())

car = Car("Honda")
bike = Bike("Yamaha")
print(car.drive())
print(bike.ride())

આકૃતિ:

MultTiepalcPehreIrfnehseRsreisrteaanrcceh:erHierarCcVaherihciaclleBIinkheeritance:

મેમરી ટ્રીક: “Multiple = ઘણા માતા-પિતા, Hierarchical = વૃક્ષ માળખું”

પ્રશ્ન 3(a) [3 ગુણ]
#

Stack પર Push અને Pop operations સમજાવો.

જવાબ:

ટેબલ: Stack Operations

Operationવર્ણનTime Complexity
Pushટોચ પર element ઉમેરવુંO(1)
Popટોચેથી element દૂર કરવુંO(1)
Peek/Topટોચનું element જોવુંO(1)
isEmptyStack ખાલી છે કે નહીં તપાસવુંO(1)
stack = []

# Push operation
stack.append(10)  # 10 Push કરો
stack.append(20)  # 20 Push કરો
print("Push પછી:", stack)  # [10, 20]

# Pop operation
item = stack.pop()  # 20 Pop કરો
print(f"Pop કર્યું: {item}, Stack: {stack}")  # [10]
  • LIFO: Last In, First Out સિદ્ધાંત
  • ટોચ: Operations માટે માત્ર accessible element

મેમરી ટ્રીક: “Stack = થાળીઓનો ઢગલો - છેલ્લી થાળી અંદર, પહેલી થાળી બહાર”

પ્રશ્ન 3(b) [4 ગુણ]
#

Queue ના Enqueue અને Dequeue operations સમજાવો.

જવાબ:

ટેબલ: Queue Operations

Operationવર્ણનસ્થાનTime Complexity
EnqueueElement ઉમેરવુંપાછળO(1)
DequeueElement દૂર કરવુંઆગળO(1)
Frontઆગળનું element જોવુંઆગળO(1)
Rearપાછળનું element જોવુંપાછળO(1)
from collections import deque

queue = deque()

# Enqueue operation
queue.append(10)  # 10 Enqueue કરો
queue.append(20)  # 20 Enqueue કરો
print("Enqueue પછી:", list(queue))  # [10, 20]

# Dequeue operation
item = queue.popleft()  # 10 Dequeue કરો
print(f"Dequeue કર્યું: {item}, Queue: {list(queue)}")  # [20]
  • FIFO: First In, First Out સિદ્ધાંત
  • બે છેડા: આગળ removal માટે, પાછળ insertion માટે

મેમરી ટ્રીક: “Queue = દુકાનમાં લાઇન - પહેલો વ્યક્તિ અંદર, પહેલો વ્યક્તિ બહાર”

પ્રશ્ન 3(c) [7 ગુણ]
#

Stack ની વિવિધ applications સમજાવો.

જવાબ:

ટેબલ: Stack Applications

Applicationવર્ણનઉદાહરણ
Expression EvaluationInfix ને postfix માં રૂપાંતર(a+b)c → ab+c
Function CallsFunction call sequence manage કરવુંRecursion handling
Undo Operationsતાજેતરની ક્રિયાઓ ઉલટાવવીText editor undo
Browser HistoryPages દ્વારા પાછળ navigate કરવુંBack button
Parentheses MatchingBalanced brackets ચકાસવા{[()]} validation
# ઉદાહરણ: Parentheses matching
def is_balanced(expression):
    stack = []
    pairs = {'(': ')', '[': ']', '{': '}'}
    
    for char in expression:
        if char in pairs:  # Opening bracket
            stack.append(char)
        elif char in pairs.values():  # Closing bracket
            if not stack:
                return False
            if pairs[stack.pop()] != char:
                return False
    
    return len(stack) == 0

# ટેસ્ટ
print(is_balanced("({[]})"))  # True
print(is_balanced("({[}])"))  # False
  • Memory Management: Programming માં function call stack
  • Backtracking: Maze solving, game algorithms
  • Compiler Design: Syntax analysis અને parsing

મેમરી ટ્રીક: “Stack Applications = UFPB (Undo, Function, Parentheses, Browser)”

પ્રશ્ન 3(a) OR [3 ગુણ]
#

Single Queue ની મર્યાદાઓની યાદી બનાવો.

જવાબ:

ટેબલ: Single Queue Limitations

મર્યાદાવર્ણનસમસ્યા
Memory Wastageઆગળની જગ્યા અનુપયોગી બને છેઅકાર્યક્ષમ memory ઉપયોગ
Fixed SizeDynamically resize કરી શકાતું નથીજગ્યાની મર્યાદા
False Overflowઆગળની જગ્યા ખાલી હોવા છતાં queue ભરેલી લાગેઅકાળે capacity limit
No ReuseDequeue કરેલી positions ફરીથી વાપરી શકાતી નથીLinear space utilization
SF[irXno]gn[ltXe][Q3u]e[u4e][P5r](o[bl]e[m:R]e[ar])
  • Linear Implementation: Dequeue કરેલી જગ્યા utilize કરી શકાતી નથી
  • Static Array: Fixed size allocation

મેમરી ટ્રીક: “Single Queue = એક બાજુનો રસ્તો (પાછા ફરી શકાતા નથી)”

પ્રશ્ન 3(b) OR [4 ગુણ]
#

Circular અને simple queues નો તફાવત લખી સમજાવો.

જવાબ:

ટેબલ: Queue Types Comparison

પાસુંSimple QueueCircular Queue
Memory UsageLinear, wastefulCircular, efficient
Space ReuseDequeue કરેલી જગ્યા ફરીથી વાપરાતી નથીબધી positions ફરીથી વાપરે છે
OverflowFalse overflow શક્યમાત્ર true overflow
ImplementationFront અને rear pointersModulo સાથે front અને rear
S[F(iXrm]op[nlXte][Q3u]e[u4Re]e:[ar])[][C5i]R(r[ec6au]rl[a3Fr]r[oQ4nu]teue:)
# Circular Queue Implementation
class CircularQueue:
    def __init__(self, size):
        self.size = size
        self.queue = [None] * size
        self.front = -1
        self.rear = -1
    
    def enqueue(self, item):
        if (self.rear + 1) % self.size == self.front:
            print("Queue ભરાઈ ગયું")
            return
        if self.front == -1:
            self.front = 0
        self.rear = (self.rear + 1) % self.size
        self.queue[self.rear] = item
    
    def dequeue(self):
        if self.front == -1:
            print("Queue ખાલી છે")
            return None
        item = self.queue[self.front]
        if self.front == self.rear:
            self.front = self.rear = -1
        else:
            self.front = (self.front + 1) % self.size
        return item

મેમરી ટ્રીક: “Circular = Ring Road (સતત), Simple = મૃત અંતનો રસ્તો”

પ્રશ્ન 3(c) OR [7 ગુણ]
#

નીચેની infix expression ને postfix માં રૂપાંતર કરો: (a * b) * (c ^ (d + e) – f)

જવાબ:

ટેબલ: Operator Precedence

OperatorPrecedenceAssociativity
^3Right to Left
*, /2Left to Right
+, -1Left to Right

Step-by-step conversion:

Expression: (a * b) * (c ^ (d + e) – f)

Step 1: (a * b) → ab*
Step 2: (d + e) → de+
Step 3: c ^ (de+) → c de+ ^
Step 4: (c de+ ^) – f → c de+ ^ f -
Step 5: (ab*) * (c de+ ^ f -) → ab* c de+ ^ f - *

અંતિમ જવાબ: ab*cde+^f-*

Algorithm:

  1. Operand: Output માં ઉમેરો
  2. ’(’: Stack માં push કરો
  3. ’)’: ‘(’ આવે ત્યાં સુધી pop કરો
  4. Operator: Higher/equal precedence pop કરો, પછી push કરો
  5. અંત: બાકીના બધા operators pop કરો
def infix_to_postfix(expression):
    precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3}
    stack = []
    output = []
    
    for char in expression:
        if char.isalnum():
            output.append(char)
        elif char == '(':
            stack.append(char)
        elif char == ')':
            while stack and stack[-1] != '(':
                output.append(stack.pop())
            stack.pop()  # '(' દૂર કરો
        elif char in precedence:
            while (stack and stack[-1] != '(' and 
                   stack[-1] in precedence and
                   precedence[stack[-1]] >= precedence[char]):
                output.append(stack.pop())
            stack.append(char)
    
    while stack:
        output.append(stack.pop())
    
    return ''.join(output)

# ટેસ્ટ
result = infix_to_postfix("(a*b)*(c^(d+e)-f)")
print("Postfix:", result)  # ab*cde+^f-*

મેમરી ટ્રીક: “Precedence માટે PEMDAS, Operators માટે Stack”

પ્રશ્ન 4(a) [3 ગુણ]
#

Linked List ના પ્રકારો સમજાવો.

જવાબ:

ટેબલ: Linked List Types

પ્રકારવર્ણનમુખ્ય વિશેષતા
Singly LinkedNext node નો એક pointerમાત્ર આગળ traversal
Doubly LinkedNext અને previous નાં pointersબંને દિશામાં traversal
Circular Linkedછેલ્લો node પહેલાને point કરેકોઈ NULL pointer નથી
Doubly CircularDoubly + Circular featuresબંને દિશા + circular
SDCDioionurugbcbllulyyly::arC:ircu[N[lAUAa]L]_rL_:[[_B[B_[]A]_A]_]_[[__C[C_[_]B]_B_]|]_N_U[[_LCC_L]]_|NULL
  • Memory: દરેક node માં data અને pointer(s) હોય છે
  • Dynamic: Runtime દરમિયાન size બદલાઈ શકે છે

મેમરી ટ્રીક: “SDCD - Singly, Doubly, Circular, Doubly-Circular”

પ્રશ્ન 4(b) [4 ગુણ]
#

Circular linked list અને singly linked list નો તફાવત લખી સમજાવો.

જવાબ:

ટેબલ: Singly vs Circular Linked List

પાસુંSingly Linked ListCircular Linked List
છેલ્લો NodeNULL ને point કરેપહેલા node ને point કરે
TraversalNULL પર અંત આવેસતત loop
Memoryછેલ્લો node NULL store કરેકોઈ NULL pointer નથી
DetectionNULL માટે check કરોશરૂઆતના node માટે check કરો
# Singly Linked List Node
class SinglyNode:
    def __init__(self, data):
        self.data = data
        self.next = None

# Circular Linked List Node
class CircularNode:
    def __init__(self, data):
        self.data = data
        self.next = None

def traverse_singly(head):
    current = head
    while current:  # NULL પર અટકે
        print(current.data)
        current = current.next

def traverse_circular(head):
    if not head:
        return
    current = head
    while True:
        print(current.data)
        current = current.next
        if current == head:  # શરૂઆતમાં પાછા
            break

આકૃતિ:

SCiinrgcluyl:ar:[[11]]__[[_22_]]__[[_33|]]NULL

મેમરી ટ્રીક: “Singly = મૃત અંત, Circular = Race Track”

પ્રશ્ન 4(c) [7 ગુણ]
#

Singly linked list માં નીચેની કામગીરી કરવા માટે એક પ્રોગ્રામનો અમલ કરો: a. Singly linked list ની શરૂઆતમાં node દાખલ કરો. b. Singly linked list ના અંતે node દાખલ કરો.

જવાબ:

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class SinglyLinkedList:
    def __init__(self):
        self.head = None
    
    def insert_at_beginning(self, data):
        """શરૂઆતમાં node insert કરો"""
        new_node = Node(data)
        new_node.next = self.head
        self.head = new_node
        print(f"{data} શરૂઆતમાં insert કર્યું")
    
    def insert_at_end(self, data):
        """અંતે node insert કરો"""
        new_node = Node(data)
        
        if not self.head:  # ખાલી list
            self.head = new_node
            print(f"{data} અંતે insert કર્યું (પહેલો node)")
            return
        
        # છેલ્લા node સુધી traverse કરો
        current = self.head
        while current.next:
            current = current.next
        
        current.next = new_node
        print(f"{data} અંતે insert કર્યું")
    
    def display(self):
        """Linked list દર્શાવો"""
        if not self.head:
            print("List ખાલી છે")
            return
        
        current = self.head
        elements = []
        while current:
            elements.append(str(current.data))
            current = current.next
        
        print(" → ".join(elements) + " → NULL")

# ઉપયોગનું ઉદાહરણ
sll = SinglyLinkedList()

# શરૂઆતમાં insert કરો
sll.insert_at_beginning(10)
sll.insert_at_beginning(20)
sll.display()  # 20 → 10 → NULL

# અંતે insert કરો
sll.insert_at_end(30)
sll.insert_at_end(40)
sll.display()  # 20 → 10 → 30 → 40 → NULL

ટેબલ: Insertion Operations

OperationTime Complexityપગલાં
શરૂઆતO(1)1. Node બનાવો 2. Head ને point કરો 3. Head update કરો
અંતO(n)1. Node બનાવો 2. અંત સુધી traverse કરો 3. છેલ્લો node link કરો

મેમરી ટ્રીક: “શરૂઆત = ઝડપથી (O(1)), અંત = પ્રવાસ (O(n))”

પ્રશ્ન 4(a) OR [3 ગુણ]
#

Doubly linked list સમજાવો.

જવાબ:

ટેબલ: Doubly Linked List Features

વિશેષતાવર્ણન
બે Pointersદરેક node માં prev અને next
Bidirectionalઆગળ અને પાછળ બંને તરફ traverse કરી શકાય
Memoryprev pointer માટે વધારાની જગ્યા
લવચીકતાગમે ત્યાં insertion/deletion સહેલું
class DoublyNode:
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None

# માળખાનું visualization
# NULL ← [prev|data|next] ⇄ [prev|data|next] → NULL
DNoUuLbLly[pArL]eivn[kBne]edx[tLCi]stNULL:
  • ફાયદા: Bidirectional traversal, સહેલું deletion
  • નુકસાન: prev pointer માટે વધારાની મેમરી

મેમરી ટ્રીક: “Doubly = બે બાજુનો રસ્તો”

પ્રશ્ન 4(b) OR [4 ગુણ]
#

Linked List ની applications નું વર્ણન કરો.

જવાબ:

ટેબલ: Linked List Applications

ApplicationUse Caseફાયદો
Dynamic Arraysજ્યારે size બદલાતું રહેકાર્યક્ષમ memory usage
Stack/QueueLIFO/FIFO operationsDynamic size
GraphsAdjacency list representationSpace efficient
Music Playlistપાછલા/આગલા ગીતોસહેલું navigation
Browser HistoryBack/Forward navigationDynamic history
Undo OperationsText editorsકાર્યક્ષમ undo/redo
# ઉદાહરણ: Doubly Linked List વાપરીને Browser History
class Page:
    def __init__(self, url):
        self.url = url
        self.prev = None
        self.next = None

class BrowserHistory:
    def __init__(self):
        self.current = None
    
    def visit(self, url):
        page = Page(url)
        if self.current:
            self.current.next = page
            page.prev = self.current
        self.current = page
    
    def back(self):
        if self.current and self.current.prev:
            self.current = self.current.prev
            return self.current.url
        return "કોઈ પાછલું page નથી"
    
    def forward(self):
        if self.current and self.current.next:
            self.current = self.current.next
            return self.current.url
        return "કોઈ આગલું page નથી"

મેમરી ટ્રીક: “Linked Lists = Dynamic, લવચીક, જોડાયેલ”

પ્રશ્ન 4(c) OR [7 ગુણ]
#

Merge Sort algorithm નો પ્રોગ્રામ લખી સમજાવો.

જવાબ:

def merge_sort(arr):
    """Merge Sort implementation"""
    if len(arr) <= 1:
        return arr
    
    # Array ને બે ભાગમાં વહેંચો
    mid = len(arr) // 2
    left_half = arr[:mid]
    right_half = arr[mid:]
    
    # બંને ભાગો recursively sort કરો
    left_sorted = merge_sort(left_half)
    right_sorted = merge_sort(right_half)
    
    # Sorted ભાગોને merge કરો
    return merge(left_sorted, right_sorted)

def merge(left, right):
    """બે sorted arrays ને merge કરો"""
    result = []
    i = j = 0
    
    # Elements compare કરીને merge કરો
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    
    # બાકીના elements ઉમેરો
    result.extend(left[i:])
    result.extend(right[j:])
    
    return result

# ઉદાહરણ
def demonstrate_merge_sort():
    arr = [64, 34, 25, 12, 22, 11, 90]
    print("મૂળ array:", arr)
    
    sorted_arr = merge_sort(arr)
    print("Sorted array:", sorted_arr)

demonstrate_merge_sort()

ટેબલ: Merge Sort Analysis

પાસુંમૂલ્ય
Time ComplexityO(n log n)
Space ComplexityO(n)
StabilityStable
પ્રકારDivide and Conquer

Algorithm પગલાં:

  1. વિભાજન: Array ને બે ભાગમાં વહેંચો
  2. જીત: બંને ભાગો recursively sort કરો
  3. જોડાણ: Sorted ભાગોને merge કરો

મેમરી ટ્રીક: “Merge Sort = વહેંચો, ગોઠવો, જોડો”

પ્રશ્ન 5(a) [3 ગુણ]
#

Binary tree ની applications નું વર્ણન કરો.

જવાબ:

ટેબલ: Binary Tree Applications

Applicationવર્ણનઉદાહરણ
Expression Treesગાણિતિક expression representation(a+b)*c
Decision TreesAI/ML માં decision makingClassification algorithms
File SystemsDirectory structure organizationFolder hierarchy
Database Indexingકાર્યક્ષમ searching માટે B-treesDatabase indices
Huffman CodingData compression techniqueFile compression
Heap OperationsPriority queues implementationTask scheduling
  • વંશવેલો Data: Tree-like structures ને કુદરતી રીતે represent કરે
  • કાર્યક્ષમ Search: Binary search trees O(log n) operations આપે
  • Memory Management: Compiler design માં syntax trees માટે વપરાય

મેમરી ટ્રીક: “Binary Trees = EDFDHH (Expression, Decision, File, Database, Huffman, Heap)”

પ્રશ્ન 5(b) [4 ગુણ]
#

ઉદાહરણ સાથે binary tree ની Indegree અને Outdegree સમજાવો.

જવાબ:

ટેબલ: Degree Definitions

શબ્દવ્યાખ્યાBinary Tree Value
IndegreeNode માં આવતા edges ની સંખ્યા0 (root) અથવા 1 (બાકી)
OutdegreeNode માંથી જતા edges ની સંખ્યા0, 1, અથવા 2
DegreeNode સાથે જોડાયેલા કુલ edgesIndegree + Outdegree
BinarDyBTrAEee(C(iin(ndidenegdgrerege:ere=e=0e1,=,1o,ouutotdudetegdgreregeere=e=2e0)=)1)
  • Root Node: હંમેશા indegree = 0
  • Leaf Nodes: હંમેશા outdegree = 0
  • Internal Nodes: outdegree = 1 અથવા 2

ટેબલ: ઉદાહરણ Analysis

NodeIndegreeOutdegreeNode Type
A02Root
B11Internal
C11Internal
D10Leaf
E10Leaf

મેમરી ટ્રીક: “In = અંદર આવતા, Out = બહાર જતા”

પ્રશ્ન 5(c) [7 ગુણ]
#

Binary search tree બનાવવા માટે પ્રોગ્રામ લખો.

જવાબ:

class TreeNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class BinarySearchTree:
    def __init__(self):
        self.root = None
    
    def insert(self, data):
        """BST માં node insert કરો"""
        if self.root is None:
            self.root = TreeNode(data)
        else:
            self._insert_recursive(self.root, data)
    
    def _insert_recursive(self, node, data):
        if data < node.data:
            if node.left is None:
                node.left = TreeNode(data)
            else:
                self._insert_recursive(node.left, data)
        elif data > node.data:
            if node.right is None:
                node.right = TreeNode(data)
            else:
                self._insert_recursive(node.right, data)
    
    def search(self, data):
        """BST માં node શોધો"""
        return self._search_recursive(self.root, data)
    
    def _search_recursive(self, node, data):
        if node is None or node.data == data:
            return node
        
        if data < node.data:
            return self._search_recursive(node.left, data)
        else:
            return self._search_recursive(node.right, data)
    
    def inorder_traversal(self):
        """Inorder traversal (ડાબે, રૂટ, જમણે)"""
        result = []
        self._inorder_recursive(self.root, result)
        return result
    
    def _inorder_recursive(self, node, result):
        if node:
            self._inorder_recursive(node.left, result)
            result.append(node.data)
            self._inorder_recursive(node.right, result)
    
    def display_tree(self):
        """સાદું tree display"""
        if self.root:
            self._display_recursive(self.root, 0)
    
    def _display_recursive(self, node, level):
        if node:
            self._display_recursive(node.right, level + 1)
            print("  " * level + str(node.data))
            self._display_recursive(node.left, level + 1)

# ઉદાહરણ
bst = BinarySearchTree()
values = [50, 30, 70, 20, 40, 60, 80]

print("મૂલ્યો insert કરી રહ્યા છીએ:", values)
for value in values:
    bst.insert(value)

print("\nTree structure:")
bst.display_tree()

print("\nInorder traversal:", bst.inorder_traversal())

# Search ઉદાહરણો
print(f"\n40 શોધો: {'મળ્યું' if bst.search(40) else 'મળ્યું નહીં'}")
print(f"90 શોધો: {'મળ્યું' if bst.search(90) else 'મળ્યું નહીં'}")

ટેબલ: BST Operations

OperationTime Complexityવર્ણન
InsertO(log n) average, O(n) worstનવો node ઉમેરો
SearchO(log n) average, O(n) worstચોક્કસ node શોધો
DeleteO(log n) average, O(n) worstNode દૂર કરો
TraversalO(n)બધા nodes ની મુલાકાત

મેમરી ટ્રીક: “BST નિયમ = ડાબે < રૂટ < જમણે”

પ્રશ્ન 5(a) OR [3 ગુણ]
#

Binary tree માં level, degree અને leaf node વ્યાખ્યાયિત કરો.

જવાબ:

ટેબલ: Binary Tree શબ્દો

શબ્દવ્યાખ્યાઉદાહરણ
LevelRoot થી અંતર (root = level 0)Root=0, Children=1, વગેરે
DegreeNode ના children ની સંખ્યા0, 1, અથવા 2
Leaf Nodeકોઈ children વગરનો node (degree = 0)Terminal nodes
LLLLeeeevvvveeeelllls012:::BDinBarAEyCTrFee:

ટેબલ: ઉદાહરણ Analysis

NodeLevelDegreeપ્રકાર
A02Root
B11Internal
C12Internal
D20Leaf
E20Leaf
F20Leaf
  • Height: Tree માં મહત્તમ level
  • Depth: એક node માટે level જેટલું જ

મેમરી ટ્રીક: “Level = માળનો નંબર, Degree = બાળકોની ગણતરી, Leaf = કોઈ બાળક નથી”

પ્રશ્ન 5(b) OR [4 ગુણ]
#

ઉદાહરણ સાથે complete binary tree સમજાવો.

જવાબ:

ટેબલ: Binary Tree પ્રકારો

પ્રકારવર્ણનગુણધર્મ
Completeછેલ્લા સિવાય બધા levels ભરેલા, ડાબેથી ભરાયકાર્યક્ષમ array representation
Fullદરેક node પાસે 0 અથવા 2 childrenએક child વાળા nodes નથી
Perfectબધા levels સંપૂર્ણ ભરેલા2^h - 1 nodes
CCoommpplDleetBtBeEeAAEBFiCCFna:GryTree:
class CompleteBinaryTree:
    def __init__(self):
        self.tree = []
    
    def insert(self, data):
        """Complete binary tree રીતે insert કરો"""
        self.tree.append(data)
    
    def get_parent_index(self, i):
        return (i - 1) // 2
    
    def get_left_child_index(self, i):
        return 2 * i + 1
    
    def get_right_child_index(self, i):
        return 2 * i + 2
    
    def display_level_order(self):
        """Tree ને level દ્વારા દર્શાવો"""
        if not self.tree:
            return
        
        level = 0
        while (2 ** level) <= len(self.tree):
            start = 2 ** level - 1
            end = min(2 ** (level + 1) - 1, len(self.tree))
            print(f"Level {level}: {self.tree[start:end]}")
            level += 1

# ઉદાહરણ
cbt = CompleteBinaryTree()
for i in [1, 2, 3, 4, 5, 6]:
    cbt.insert(i)

cbt.display_level_order()

ગુણધર્મો:

  • Array Representation: Parent i પર, children 2i+1 અને 2i+2 પર
  • Heap Property: Heap data structure નો આધાર બને

મેમરી ટ્રીક: “Complete = છેલ્લા સિવાય બધા માળ ભરેલા, ડાબેથી જમણે ભરાય”

પ્રશ્ન 5(c) OR [7 ગુણ]
#

નીચેના નંબરોના ક્રમ માટે binary search tree (BST) બનાવો: 50, 70, 60, 20, 90, 10, 40, 100

જવાબ:

Step-by-step BST Construction:

Insert 50: (Root)
    50

Insert 70: (70 > 50, જમણે જાઓ)
    50
     \
      70

Insert 60: (60 > 50, જમણે જાઓ; 60 < 70, ડાબે જાઓ)
    50
     \
      70
     /
    60

Insert 20: (20 < 50, ડાબે જાઓ)
    50
   /  \
  20   70
       /
      60

Insert 90: (90 > 50, જમણે; 90 > 70, જમણે)
    50
   /  \
  20   70
       / \
      60  90

Insert 10: (10 < 50, ડાબે; 10 < 20, ડાબે)
    50
   /  \
  20   70
 /    / \
10   60  90

Insert 40: (40 < 50, ડાબે; 40 > 20, જમણે)
    50
   /  \
  20   70
 / \   / \
10  40 60 90

Insert 100: (100 > 50, જમણે; 100 > 70, જમણે; 100 > 90, જમણે)
    50
   /  \
  20   70
 / \   / \
10  40 60 90
             \
              100

અંતિમ BST માળખું:

10205400760090100
# Construction માટે implementation code
class BST:
    def __init__(self):
        self.root = None
    
    def insert(self, data):
        if self.root is None:
            self.root = TreeNode(data)
            print(f"{data} ને root તરીકે insert કર્યું")
        else:
            self._insert(self.root, data)
    
    def _insert(self, node, data):
        if data < node.data:
            if node.left is None:
                node.left = TreeNode(data)
                print(f"{data} ને {node.data} ના ડાબે insert કર્યું")
            else:
                self._insert(node.left, data)
        else:
            if node.right is None:
                node.right = TreeNode(data)
                print(f"{data} ને {node.data} ના જમણે insert કર્યું")
            else:
                self._insert(node.right, data)

# BST બનાવો
bst = BST()
sequence = [50, 70, 60, 20, 90, 10, 40, 100]

for num in sequence:
    bst.insert(num)

ટેબલ: Traversal પરિણામો

Traversalપરિણામ
Inorder10, 20, 40, 50, 60, 70, 90, 100
Preorder50, 20, 10, 40, 70, 60, 90, 100
Postorder10, 40, 20, 60, 100, 90, 70, 50

ચકાસાયેલા ગુણધર્મો:

  • BST Property: ડાબું subtree < Root < જમણું subtree
  • Inorder: Sorted sequence આપે છે

મેમરી ટ્રીક: “BST Construction = તુલના કરો, દિશા પસંદ કરો, Insert કરો”

સંબંધિત

ફંડામેન્ટલ્સ ઓફ ઇલેક્ટ્રોનિક્સ (4311102) - સમર 2023 સોલ્યુશન
22 મિનિટ
અભ્યાસ-સામગ્રી સોલ્યુશન ઇલેક્ટ્રોનિક્સ 4311102 2023 સમર
ડિજિટલ માર્કેટિંગના આવશ્યક તત્વો (4341601) - ઉનાળા 2023 સોલ્યુશન
અભ્યાસ-સામગ્રી સોલ્યુશન ડિજિટલ-માર્કેટિંગ 4341601 2023 ઉનાળા
ઇન્ડસ્ટ્રિયલ ઇલેક્ટ્રોનિક્સ (4331103) - ગ્રીષ્મ 2023 સોલ્યુશન
અભ્યાસ-સામગ્રી સોલ્યુશન્સ ઇન્ડસ્ટ્રિયલ-ઇલેક્ટ્રોનિક્સ 4331103 2023 ગ્રીષ્મ
ઇલેક્ટ્રોનિક મેઝરમેન્ટ્સ એન્ડ ઇન્સ્ટ્રુમેન્ટ્સ (4331102) - વિન્ટર 2022 સોલ્યુશન
અભ્યાસ-સામગ્રી સોલ્યુશન ઇલેક્ટ્રોનિક-મેઝરમેન્ટ્સ 4331102 2022 વિન્ટર
Python Programming (4311601) - Summer 2023 Solution (Gujarati)
Study-Material Solutions Python 4311601 2023 Summer Gujarati
ઇલેક્ટ્રોનિક કમ્યુનિકેશનના સિદ્ધાંતો (4331104) - ગ્રીષ્મ 2023 સોલ્યુશન
Study-Material Solutions Electronic-Communication 4331104 2023 Summer