📜  门| GATE CS 2021 |套装2 |第59章(1)

📅  最后修改于: 2023-12-03 15:12:37.491000             🧑  作者: Mango

GATE CS 2021 套装2 第59章 介绍

本章主要考查程序设计中的算法和数据结构。涉及的主要内容包括排序、查找、图论等。在理解和掌握这些知识点前,需要对基本的数据结构(数组、链表、树、图)和基本算法(递归、分治、动态规划等)有一定的掌握。

排序算法

排序算法是计算机程序设计中常用的算法。常用的排序算法有冒泡排序、插入排序、选择排序、归并排序、快速排序等。理解排序算法的原理和复杂度分析是本章的重点。

冒泡排序的基本思想是通过交换相邻的元素,在每一轮排序中把最大的元素浮到最后面。时间复杂度为 O(n^2)。

def bubbleSort(arr):
    n = len(arr)

    for i in range(n):
        # Last i elements are already in place
        for j in range(0, n-i-1):
            # Traverse the array from 0 to n-i-1
            # Swap if the element found is greater
            # than the next element
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]

插入排序的基本思想是将一个元素插入到已经排好序的一组元素中,时间复杂度也是 O(n^2)。

def insertionSort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j >=0 and key < arr[j] :
                arr[j+1] = arr[j]
                j -= 1
        arr[j+1] = key

快速排序是一种基于比较的排序算法,也是面试中较为常见的算法。快速排序的基本思想是在待排序的元素中选取一个元素作为基准,然后将小于基准的元素放到左边,大于等于基准的元素放到右边,然后递归处理左右两个子序列。

def quickSort(arr, low, high):
    if low < high:
        # pi is partitioning index, arr[p] is now
        # at right place
        pi = partition(arr,low,high)

        # Separately sort elements before
        # partition and after partition
        quickSort(arr, low, pi-1)
        quickSort(arr, pi+1, high)
def partition(arr, low, high):
    i = ( low-1 )         # index of smaller element
    pivot = arr[high]     # pivot

    for j in range(low , high):

        # If current element is smaller than or
        # equal to pivot
        if   arr[j] <= pivot:

            # increment index of smaller element
            i = i+1
            arr[i],arr[j] = arr[j],arr[i]

    arr[i+1],arr[high] = arr[high],arr[i+1]
    return ( i+1 )
查找算法

查找算法是程序设计中常见的一种算法。主要包括线性查找和二分查找。线性查找的时间复杂度为 O(n),二分查找的时间复杂度为 O(logn)。

def linearSearch(arr, x):
    for i in range(len(arr)):
        if arr[i] == x:
            return i
    return -1

def binarySearch (arr, l, r, x):
    # Check base case
    if r >= l:

        mid = l + (r - l) // 2

        # If element is present at the middle
        if arr[mid] == x:
            return mid

        # If element is smaller than mid
        elif arr[mid] > x:
            return binarySearch(arr, l, mid-1, x)

        # Else the element is in right side
        else:
            return binarySearch(arr, mid + 1, r, x)

    else:
        # Element is not present in array
        return -1
图论

图论是研究图形和网络的数学理论。在程序设计中,图被广泛应用于网络、路径查找等领域。本章主要讨论基本的图论算法,包括深度优先搜索(DFS)、广度优先搜索(BFS)和最短路径算法。

深度优先搜索是一种递归的查找方法,能够遍历整张图,时间复杂度为 O(n)。

# Python3 program to print DFS traversal from a 
# given graph 
from collections import defaultdict 

# This class represents a directed graph using 
# adjacency list representation 
class Graph: 

    # Constructor 
    def __init__(self): 
        # default dictionary to store graph 
        self.graph = defaultdict(list) 

    # function to add an edge to graph 
    def addEdge(self,u,v): 
        self.graph[u].append(v) 

    # A function used by DFS 
    def DFSUtil(self,v,visited): 
        # Mark the current node as visited and print it 
        visited.add(v) 
        print(v, end=' ') 

        # Recur for all the vertices adjacent to this vertex 
        for neighbour in self.graph[v]: 
            if neighbour not in visited: 
                self.DFSUtil(neighbour, visited) 

    # The function to do DFS traversal. It uses 
    # recursive DFSUtil() 
    def DFS(self,v): 
        # Create a set to store visited vertices 
        visited = set() 

        # Call the recursive helper function 
        # to print DFS traversal 
        self.DFSUtil(v,visited)

广度优先搜索也是一种遍历图的方法,不同于深度优先搜索的是,广度优先搜索是逐层遍历,时间复杂度也是 O(n)。

# Python3 program to print BFS traversal from a 
# given source vertex. BFS(int s) traverses vertices  
# reachable from s. 
from collections import defaultdict 

# This class represents a directed graph using 
# adjacency list representation 
class Graph: 

    # Constructor 
    def __init__(self): 

        # default dictionary to store graph 
        self.graph = defaultdict(list) 

    # function to add an edge to graph 
    def addEdge(self,u,v): 
        self.graph[u].append(v) 

    # Function to print a BFS of graph 
    def BFS(self, s): 

        # Mark all the vertices as not visited 
        visited = [False] * (max(self.graph) + 1)

        # Create a queue for BFS 
        queue = [] 

        # Mark the source node as  
        # visited and enqueue it 
        queue.append(s) 
        visited[s] = True

        while queue: 

            # Dequeue a vertex from  
            # queue and print it 
            s = queue.pop(0) 
            print (s, end = " ") 

            # Get all adjacent vertices of the 
            # dequeued vertex s. If a adjacent 
            # has not been visited, then mark it 
            # visited and enqueue it 
            for i in self.graph[s]: 
                if visited[i] == False: 
                    queue.append(i) 
                    visited[i] = True

最短路径算法是一种寻找图中两个节点之间的最短路径的算法。常用的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。迪杰斯特拉算法的时间复杂度为 O(n^2),弗洛伊德算法的时间复杂度为 O(n^3)。

# Python Program for Floyd Warshall Algorithm 

# Number of vertices in the graph 
V = 4 

# Define infinity as the large enough value. This value will be 
# used for vertices not connected to each other 
INF = 99999

# Solves all pair shortest path via Floyd Warshall Algorithm 
def floydWarshall(graph): 

	""" dist[][] will be the output matrix that will finally 
		have the shortest distances between every pair of vertices """
	""" initializing the solution matrix same as input graph matrix 
		OR we can say that the initial values of shortest distances 
		are based on shortest paths considering no 
		intermediate vertices """
	dist = list(map(lambda i : list(map(lambda j : j , i)), graph)) 

	""" Add all vertices one by one to the set of intermediate 
		vertices. 
		---> Before start of an iteration, we have shortest distances 
		between all pairs of vertices such that the shortest 
		distances consider only the vertices in the set 
		{0, 1, 2, .. k-1} as intermediate vertices. 
		----> After the end of an iteration, vertex no. k is 
		added to the set of intermediate vertices and the 
		set becomes {0, 1, 2, .. k} 
		""" 
	for k in range(V): 

		# pick all vertices as source one by one 
		for i in range(V): 

			# Pick all vertices as destination for the 
			# above picked source 
			for j in range(V): 

				# If vertex k is on the shortest path from 
				# i to j, then update the value of dist[i][j] 
				dist[i][j] = min(dist[i][j] , 
								dist[i][k]+ dist[k][j] 
								) 
	printSolution(dist) 

# A utility function to print the solution 
def printSolution(dist): 
	print "Following matrix shows the shortest distances\ 
	between every pair of vertices" 
	for i in range(V): 
		for j in range(V): 
			if(dist[i][j] == INF): 
				print "%7s" %("INF"), 
			else: 
				print "%7d\t" %(dist[i][j]), 
			if j == V-1: 
				print "" 

# Driver program to test the above program 
# Let us create the following weighted graph 
""" 
			10 
	(0)------->(3) 
		|	 /|\ 
	5 |	 | 
		|	 | 1 
	\|/	 | 
	(1)------->(2) 
			3 
"""
graph = [[0,5,INF,10], 
		[INF,0,3,INF], 
		[INF, INF, 0, 1], 
		[INF, INF, INF, 0] 
		] 
# Print the solution 
floydWarshall(graph);