📅  最后修改于: 2023-12-03 15:12:37.491000             🧑  作者: Mango
本章主要考查程序设计中的算法和数据结构。涉及的主要内容包括排序、查找、图论等。在理解和掌握这些知识点前,需要对基本的数据结构(数组、链表、树、图)和基本算法(递归、分治、动态规划等)有一定的掌握。
排序算法是计算机程序设计中常用的算法。常用的排序算法有冒泡排序、插入排序、选择排序、归并排序、快速排序等。理解排序算法的原理和复杂度分析是本章的重点。
冒泡排序的基本思想是通过交换相邻的元素,在每一轮排序中把最大的元素浮到最后面。时间复杂度为 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);