• 算法(2):数据结构


    数据结构:

    数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成
    简单来说, 数据结构就是设计数据以何种方式组织度存储在计算机中
    比如:列表、集合和字典等都是一种数据结构
    “程序=数据结构+算法”

    数据结构的分类:

    数据结构按照逻辑结构可分为线性结构、树结构和图结构
    线性结构:数据结构中的元素存在一对一的相互关系
    树结构:数据结构中的元素存在一对多的相互关系
    图结构:数据结构中的元素存在多对多的相互关系

    另外,32位机器上,一个整数占4个字节(4*8bit=32),一个地址也占4个字节

    栈:

    栈(Stack)是一个数据集合,可以理解为只能在一端进行插入或删除操作的列表

    栈的特点:后进先出(last-in,first-out)
    栈的概念:栈顶(表尾;最后一个元素),栈底(表头;0号元素)
    栈的基本操作:
        进栈(压栈):push
        出栈:pop
        取栈顶(只查看栈顶的值,但不把栈顶删除): gettop
    使用一般的列表结构即可实现栈

    栈的应用 -- 括号匹配问题:

    括号匹配问题:给一个字符串,其中包含小括号、中括号、大括号,求该字符串中的括号是否匹配
    如:
        ()[]{}  # 匹配
        ([{()}])  # 匹配
        []( # 不匹配
        [(])  # 不匹配

    示例代码:

    class BracketError(BaseException):
        def __init__(self,msg):
            super(BracketError,self).__init__()
            self.msg = msg
    
        def __str__(self):
            return "<%s>" %self.msg
    
    class Stack(object):
        """实现栈的类"""
        def __init__(self):
            self.stack = []
    
        def push(self,ele):
            self.stack.append(ele)
        def pop(self):
            if len(self.stack) == 0:
                return None
            return self.stack.pop()
        def get_top(self):
            if len(self.stack) == 0:
                return None
            return self.stack[-1]
    
        def is_empty(self):
            return len(self.stack) == 0  # 返回的是一个Bool值
    
    # 栈的应用:括号匹配问题
    def bracket_match(s):
        stack = Stack()
        match_dict = {
            ")":"(",
            "]":"[",
            "}":"{"
        }
        for char in s:
            if char in ["(","[","{"]: # char 为左括号
                stack.push(char)  # 左括号放到 栈 里面
            else:  # char 为右括号
                if stack.is_empty():
                    raise BracketError("%s expected"%match_dict[char])
                left_bracket = stack.get_top()
                if match_dict[char] != left_bracket:
                    raise BracketError("%s not match"%char)
                else:
                    stack.pop()
        if not stack.is_empty():
            raise BracketError("lacking corresponding right brackets")
    
    s = "}[]()"
    bracket_match(s)

    链表

    1. 链表定义:

    # 链表是由一系列节点组成的元素集合。每个节点包含两部分:数据域item 和 指向下一个节点的指针next。通过节点之间的相互连接,最终串联成一个链表

    示意图:

    示例代码:

    class Node(object):
        def __init__(self,item):
            self.item = item
            self.next = None
    
    a = Node(1)
    b = Node(2)
    c = Node(3)
    
    # 把 a 和 b, c 连接起来
    a.next = b    
    b.next = c
    
    print(a.next.item)
    print(a.next.next.item)
    
    # 打印结果:
    # 2
    # 3

    2. 链表的创建和定义

    链表的创建:
    1) 头插法:插到头节点前面
    2) 尾插法:插到尾节点后面
    
    # 示例代码:
    
    class Node(object):
        def __init__(self,item):
            self.item = item
            self.next = None
    
    def create_linkedlist_head(li):        # 通过列表进行 头插法 创建链表
        head = Node(li[0])    # 利用列表的第一个元素创建链表头(头节点)
        
        for ele in li[1:]:
            node = Node(ele)    # 创建链表头的上一个节点
    
            # 新创建的这个节点的 next 指向 头节点,然后让新创建的这个节点作为头节点
            node.next = head
            head = node
    
        return head  # 返回头节点
    
    def print_linkedlist(lk):
        # 链表的遍历
        while lk:    # 节点不为空
            print(lk.item, end=",")
            lk = lk.next
        print()
    
    lk1 = create_linkedlist_head([1,2,3])
    print_linkedlist(lk1)
    
    # print_linkedlist(lk1) 执行结果: 
    # 3,2,1,
    
    def create_linkedlist_tail(li):        # 通过列表 尾插法 创建链表
        head = Node(li[0])    
        tail = head          # 此处必须通过这种赋值方式,才能让 最初的tail 指向 head; 如果 tail = Node(li[0]) ,此时 tail 和 head 是不同的 Node 实例
        
        for ele in li[1:]:
            node = Node(ele)
            # 创建新节点,上一个tail的next指向这个新节点,然后让这个新节点成为 tail 节点
            tail.next = node
            tail = node
        return head
    
    lk2 = create_linkedlist_tail([1,2,3,6,8])
    print_linkedlist(lk2)
    # 上面打印结果:
    # 1,2,3,6,8,

    链表节点的插入和删除

    插入:

    代码:

    p.next = curNode.next
    curNode.next = p
    # 上面两步的顺序不能反,即应该先把 4 和 2 链起来,两把 1 和 4 链起来

    删除:

    代码:

    curNode.next = curNode.next.next

    双链表

    # 双链表的每个节点有两个指针:一个指向后一个节点,另一个指向前一个节点
    
    class Node(object):
        def __init__(self,item=None):
            self.item = item
            self.next = None
            self.prior = None

    示意图:

    双链表的插入和删除:

    # 双链表的插入
    p.next = curNode.next
    curNode.next.prior = p
    p.prior = curNode
    curNode.next = p
    
    # 双链表的删除
    p = curNode.next
    curNode.next = p.next
    p.next.prior = curNode
  • 相关阅读:
    ES6 解构
    一些vue的知识点
    CSS选择器
    Django学习--介绍Django
    正则表达式
    ftp命令
    Vim学习指南
    关于ACM与OJ
    brctl命令
    LXC
  • 原文地址:https://www.cnblogs.com/neozheng/p/9799384.html
Copyright © 2020-2023  润新知