1. 什么是数据结构
数据结构是计算机科学中一门重要的学科,它研究各种不同数据类型的存储方式、组织方式以及访问方式。数据结构是计算机存储、处理数据的基础,因此它是编程中必不可少的一部分。
举例:在Python中,列表是一种常见的数据结构,可以存储多个元素,并通过下标方式访问。
# 定义一个列表
my_list = [1, 2, 3, 4, 5]
# 访问列表中的元素
print(my_list[0]) # 输出结果为 1
2. 常见数据结构
2.1 数组
数组是一种线性的数据结构,可以存储一组具有相同数据类型的元素,通过下标的方式访问数组中的元素。在Python中,列表可以看做是一种动态数组,它可以存储不同类型的数据。
# 定义一个整数型数组
my_array = [1, 2, 3, 4, 5]
# 访问数组中的元素
print(my_array[0]) # 输出结果为 1
2.2 队列
队列是一种先进先出(FIFO)的线性数据结构。它只允许在队列的一端进行插入操作,在另一端进行删除操作。在Python中,队列可以通过使用queue模块来实现。
import queue
# 定义一个队列
my_queue = queue.Queue()
# 向队列中添加元素
my_queue.put(1)
# 从队列中获取元素
print(my_queue.get()) # 输出结果为 1
2.3 栈
栈是一种后进先出(LIFO)的线性数据结构。栈只允许在栈顶进行插入和删除操作。在Python中,栈可以通过使用list来实现。
# 定义一个栈
my_stack = []
# 向栈中添加元素
my_stack.append(1)
# 从栈中弹出元素
print(my_stack.pop()) # 输出结果为 1
2.4 链表
链表也是一种线性数据结构,它是由节点组成的序列。每个节点包含元素本身和指向下一个节点的指针。在Python中,链表可以通过使用Node类来实现。
class Node:
def __init__(self, data):
self.data = data
self.next = None
# 定义一个链表
my_list = Node(1)
my_list.next = Node(2)
my_list.next.next = Node(3)
# 遍历链表中的元素
current_node = my_list
while current_node:
print(current_node.data)
current_node = current_node.next
2.5 树
树是一种非线性的数据结构,它由节点和边组成。树的每个节点可以有多个后继节点,但每个节点只有一个前驱节点。树有多种不同的变种,如二叉树、二叉搜索树等。在Python中,树可以通过使用Node类和递归函数来实现。
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# 插入节点
def insert_node(node, data):
if not node:
return Node(data)
if data < node.data:
node.left = insert_node(node.left, data)
else:
node.right = insert_node(node.right, data)
return node
# 遍历二叉搜索树中的元素
def inorder_traversal(node):
if node:
inorder_traversal(node.left)
print(node.data)
inorder_traversal(node.right)
# 定义一个二叉搜索树
my_tree = None
my_tree = insert_node(my_tree, 4)
my_tree = insert_node(my_tree, 2)
my_tree = insert_node(my_tree, 6)
my_tree = insert_node(my_tree, 1)
my_tree = insert_node(my_tree, 3)
my_tree = insert_node(my_tree, 5)
my_tree = insert_node(my_tree, 7)
# 中序遍历二叉搜索树
inorder_traversal(my_tree)
3. 数据结构的应用
数据结构是计算机程序中广泛使用的基础内容。在实际编程中,我们可以利用各种不同的数据结构,来帮助我们更好地解决具体的问题。
3.1 用树来实现面试题38——字符串的排列
面试题38——字符串的排列要求我们对给定的字符串,输出它的所有排列组合。
def permutation(string):
def backtrack(start=0):
if start == len(string) - 1:
res.append(''.join(string))
return
for i in range(start, len(string)):
string[start], string[i] = string[i], string[start]
backtrack(start+1)
string[start], string[i] = string[i], string[start]
res = []
string = list(string)
backtrack()
return res
# 测试
print(permutation('abc'))
上述代码中使用了回溯的方法,对给定的字符串进行全排列。但实际上回溯法的时间复杂度很高,需要优化。
我们可以发现,字符串的排列可以看作是一棵树,树的根节点对应该字符串的第一个字符,其后的节点分别对应该字符串后面的每一个字符。我们可以使用深度优先搜索(DFS)来遍历这个树。具体做法就是交换字符串中的字符,然后递归地对剩下的字符进行全排列。
举例:对于字符串'abc',我们可以先选择a,然后对剩余的'b'和'c'进行全排列。下一步我们可以选择b,然后对剩余的'c'进行全排列,最终输出结果。
3.2 用堆来实现面试题40——最小的k个数
面试题40——最小的k个数要求我们从输入的n个整数中,找出最小的k个数。
def get_least_numbers(nums, k):
import heapq
if not nums or k <= 0 or k > len(nums):
return []
return heapq.nsmallest(k, nums)
# 测试
print(get_least_numbers([4, 5, 1, 6, 2, 7, 3, 8], 4))
上述代码中我们使用了Python中内置的heapq模块,通过heapq.nsmallest()方法来获取最小的k个数。
4. 总结
数据结构是计算机编程的基础,它帮助我们更好地组织和管理数据。在实际编程中,我们可以根据具体的问题需要,选择不同的数据结构来提高程序的效率。