Python 数据结构与算法

1、算法概念


在计算机科学中,算法是一个解决特定问题或执行特定任务的有序步骤的有限序列。算法是对一系列输入数据进行处理,产生期望输出结果的一种有效方法。它是解决问题的一种清晰而精确的描述,可以被实现为计算机程序。

算法必须满足以下关键特性:

  1. 有限性(Finiteness): 算法的执行必须在有限的步骤内终止,不会永无止境地执行下去。

  2. 确定性(Determinism): 对于给定的输入,算法的每一步都有确切的定义,不会产生模糊或不确定的结果。

  3. 输入(Input): 算法接受零个或多个输入,这些输入是算法在执行过程中处理的原始数据。

  4. 输出(Output): 算法产生至少一个输出,这是由输入经过一系列步骤计算得到的结果。

  5. 效率(Effectiveness): 算法必须在有限时间内执行,而且在解决问题上是有效的,不会消耗过多的资源。

 2、时间复杂度和空间复杂度


Python(算法)-时间复杂度和空间复杂度-CSDN博客

 3、排序算法


3.1  冒泡排序

3.1.1 解释

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

冒泡排序的时间复杂度为O(n^2),其中n是数组的大小。尽管冒泡排序在时间复杂度上相对较高,但是它实现简单直观,对于小规模的数据集仍然是一种有效的排序方法。此外,冒泡排序还具有稳定性,即相等元素的相对顺序不会改变。

3.1.2 python代码

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



    # 外层循环控制比较的轮数
    for i in range(n):
        # 标记是否在本轮比较中发生交换
        swapped = False

        # 内层循环执行相邻元素的比较和交换
        for j in range(n - 1 - i):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                print("ll",arr)
                swapped = True

        # 如果本轮比较中没有发生交换,则表示数组已经有序,跳出循环
        if not swapped:
            break

    return arr


# 测试

arr = [64, 34, 25, 12, 22, 11, 90]
sorted_arr = bubble_sort(arr)
print("排序后的数组:", sorted_arr)

 3.1.3 结果

C:\Users\Thinkpad\AppData\Local\Programs\Python\Python39\python.exe C:/Users/Thinkpad/Desktop/python的数据结构/冒泡排序.py 
ll [34, 64, 25, 12, 22, 11, 90]
ll [34, 25, 64, 12, 22, 11, 90]
ll [34, 25, 12, 64, 22, 11, 90]
ll [34, 25, 12, 22, 64, 11, 90]
ll [34, 25, 12, 22, 11, 64, 90]
ll [25, 34, 12, 22, 11, 64, 90]
ll [25, 12, 34, 22, 11, 64, 90]
ll [25, 12, 22, 34, 11, 64, 90]
ll [25, 12, 22, 11, 34, 64, 90]
ll [12, 25, 22, 11, 34, 64, 90]
ll [12, 22, 25, 11, 34, 64, 90]
ll [12, 22, 11, 25, 34, 64, 90]
ll [12, 11, 22, 25, 34, 64, 90]
ll [11, 12, 22, 25, 34, 64, 90]
排序后的数组: [11, 12, 22, 25, 34, 64, 90]

Process finished with exit code 0

        3.1.4 参考文献Python 冒泡排序 | 菜鸟教程 (runoob.com)

以上对数据排序在菜鸟都有

4、数据结构

4.1  定义

在Python中,常见的数据结构定义包括以下几种:

  1. 列表(List):列表是Python中最常用的数据结构之一,用于存储一组有序的元素。列表使用方括号[]来定义,其中的元素可以是任意数据类型,并且可以动态增加、删除或修改。
my_list = [1, 2, 3, 'apple', 'banana']

  1. 元组(Tuple):元组与列表类似,不同之处在于元组使用圆括号()来定义,一旦创建就不能被修改(即元组是不可变的)。
my_tuple = (1, 2, 3, 'apple', 'banana')

  1. 字典(Dictionary):字典是无序的键值对集合,用大括号{}来定义,可以通过键来访问对应的值。字典的键必须是唯一的,但值可以重复。
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}

  1. 集合(Set):集合是一种无序的、不重复的数据集合,用大括号{}来定义,可以进行集合运算(如并集、交集、差集等)。
my_set = {1, 2, 3, 4, 5}

  1. 字符串(String):字符串是由字符组成的有序序列,可以用单引号''、双引号""或三引号''' '''来定义。
my_string = "Hello, Python!"

这些是Python中常见的数据结构定义方式,代表的是我们的数据应该怎么定义组织

  4.2 二叉树

4.2.1 二叉树基本概念

  1. 二叉树(Binary Tree):二叉树是一种树形数据结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的节点通常由一个存储元素值的数据域、一个指向左子节点的指针和一个指向右子节点的指针组成。如果某个节点没有子节点,则相应的指针可以为空。

  2. 根节点(Root Node):树中的顶层节点称为根节点。在二叉树中,根节点是整个树的起始节点,它没有父节点。

  3. 父节点(Parent Node):每个节点除了根节点外,都有一个父节点,父节点是指向当前节点的直接上级节点。

  4. 子节点(Child Node):每个节点可能有零个、一个或两个子节点。子节点是当前节点的直接下级节点。

  5. 叶子节点(Leaf Node):没有子节点的节点称为叶子节点,也叫终端节点。

  6. 内部节点(Internal Node):除了叶子节点外的其他节点都称为内部节点。内部节点既有父节点也有子节点。

  7. 深度(Depth):节点的深度是指从根节点到该节点的唯一路径的长度。根节点的深度为0,依次往下递增。

  8. 高度(Height):节点的高度是指从该节点到一个叶子节点的最长路径的长度。叶子节点的高度为0,依次往上递增。

  9. 子树(Subtree):在二叉树中,每个节点都可以作为子树的根节点,该节点下的所有子节点和它们的子节点组成了一个子树。

  10. 左子树和右子树(Left Subtree and Right Subtree):每个节点都有一个左子节点和一个右子节点,它们分别称为左子树和右子树。

4.3 二叉树代码


class Node(object):
    """树节点"""

    def __init__(self, item):
        self.item = item
        self.left_child = None
        self.right_child = None


class BinaryTree(object):
    """二叉树"""

    def __init__(self):
        self.root = None

    def is_empty(self):
        """判断二叉树是否为空"""
        return self.root is None

    def add(self, item):
        """添加树节点"""
        node = Node(item)
        if self.root is None:
            self.root = node
            return
        temp = [self.root]
        # print(temp)
        while temp:
            current_node = temp.pop(0) #移除列表最后一个元素
            if current_node.left_child:
                temp.append(current_node.left_child)
            else:
                current_node.left_child = node
                return
            if current_node.right_child:
                temp.append(current_node.right_child)
            else:
                current_node.right_child = node
                return
        '''
            广度优先遍历(层次遍历)
            从树的root开始,从上到下从从左到右遍历整个树的节点
            '''
    def breadth_traversal(self):
        """广度遍历"""
        if self.root is None:
            return
        temp = [self.root]
        while temp:
            current_node = temp.pop(0)
            print(current_node.item, end=' ')
            if current_node.left_child:
                temp.append(current_node.left_child)
            if current_node.right_child:
                temp.append(current_node.right_child)
        print()

    '''
        深度优先遍历
        对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
        那么深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做
        先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。我们来给出它们的详细定义,然后举例看看它们的应用。

        先序遍历
        在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树
        先序遍历 在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树

         顺序如右:根节点->左子树->右子树
        '''

    def preorder_traversal(self, node):
        """先序遍历"""
        if node is None:
            return
        print(node.item, end=' ')
        self.preorder_traversal(node.left_child)
        self.preorder_traversal(node.right_child)
        """
        中序遍历 在中序遍历中,我们递归使用中序遍历访问左子树,然后访问根节点,最后再递归使用中序遍历访问右子树

        顺序如右:左子树->根节点->右子树
        """
    def inorder_traversal(self, node):
        """中序遍历"""
        if node is None:
            return
        self.inorder_traversal(node.left_child)
        print(node.item, end=' ')
        self.inorder_traversal(node.right_child)




    """
    后序遍历 在后序遍历中,我们先递归使用后序遍历访问左子树和右子树,最后访问根节点

顺序如右:左子树->右子树->根节点
代码实现:
    """


    def postorder_traversal(self, node):
        """后序遍历"""
        if node is None:
            return
        self.postorder_traversal(node.left_child)
        self.postorder_traversal(node.right_child)
        print(node.item, end=' ')


if __name__ == '__main__':
    tree = BinaryTree()
    print(tree.is_empty())
    tree.add(0)
    tree.add(1)
    tree.add(2)
    tree.add(3)
    tree.add(4)
    tree.add(5)
    tree.add(6)
    tree.add(7)
    tree.add(8)
    tree.add(9)
    print(tree.is_empty())
    print("广度遍历")
    tree.breadth_traversal()
    print("先序遍历")
    tree.preorder_traversal(tree.root)
    print("\n中序遍历")
    tree.inorder_traversal(tree.root)
    print("\n后序遍历")
    tree.postorder_traversal(tree.root)

 4.3.1 运行结果

C:\Users\Thinkpad\AppData\Local\Programs\Python\Python39\python.exe C:/Users/Thinkpad/Desktop/python的数据结构/二叉树.py 
True
False
广度遍历
0 1 2 3 4 5 6 7 8 9 
先序遍历
0 1 3 7 8 4 9 2 5 6 
中序遍历
7 3 8 1 9 4 0 5 2 6 
后序遍历
7 8 3 9 4 1 5 6 2 0 
Process finished with exit code 0
 

算法数据结构Python书》是一本介绍Python编程语言中算法数据结构的书籍。该书主要分为两个部分,第一部分介绍了Python编程语言的基础知识,包括Python的数据类型、控制流、函数、模块等内容。第二部分则介绍了Python中常用的算法数据结构,包括数组、链表、栈、队列、树、图等。 以下是该书中的一些例子: 1.使用Python实现二分查找算法 ```python def binary_search(arr, x): low = 0 high = len(arr) - 1 mid = 0 while low <= high: mid = (high + low) // 2 if arr[mid] < x: low = mid + 1 elif arr[mid] > x: high = mid - 1 else: return mid return -1 ``` 2.使用Python实现快速排序算法 ```python def quicksort(arr): if len(arr) <= 1: return arr else: pivot = arr[0] less = [x for x in arr[1:] if x <= pivot] greater = [x for x in arr[1:] if x > pivot] return quicksort(less) + [pivot] + quicksort(greater) ``` 3.使用Python实现哈希表数据结构 ```python class HashTable: def __init__(self): self.size = 11 self.slots = [None] * self.size self.data = [None] * self.size def put(self, key, data): hashvalue = self.hashfunction(key,len(self.slots)) if self.slots[hashvalue] == None: self.slots[hashvalue] = key self.data[hashvalue] = data else: if self.slots[hashvalue] == key: self.data[hashvalue] = data #replace else: nextslot = self.rehash(hashvalue, len(self.slots)) while self.slots[nextslot] != None and \ self.slots[nextslot] != key: nextslot = self.rehash(nextslot, len(self.slots)) if self.slots[nextslot] == None: self.slots[nextslot]=key self.data[nextslot]=data else: self.data[nextslot] = data #replace def hashfunction(self,key,size): return key%size def rehash(self,oldhash,size): return (oldhash+1)%size def get(self,key): startslot = self.hashfunction(key,len(self.slots)) data = None stop = False found = False position = startslot while self.slots[position] != None and \ not found and not stop: if self.slots[position] == key: found = True data = self.data[position] else: position=self.rehash(position,len(self.slots)) if position == startslot: stop = True return data def __getitem__(self,key): return self.get(key) def __setitem__(self,key,data): self.put(key,data) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值