zoukankan      html  css  js  c++  java
  • 数据结构

     

    1、什么是数据结构?

    数据结构是指相互之间存在着一种或者多种关系的数据元素的集合和该集合中数据元素之间的关系组成

    数据结构就是设计数据以何种方式组织并存储在计算机中。

    2、数据结构按照其逻辑结构可以分为,线性结构;树结构;图结构

    线性结构:数据结构中的元素存在一对一的相互关系;比如列表,有一个前驱,一个后继

    树结构:数据结构中的元素存在一对多的相互关系;有一个前驱,多个后继

    图结构:数据结构中的元素存在多对多的相互关系;有多个前驱,多个后继

    3、c语言的数组和python中列表的不同?

    c语言数组1、元素的类型一样;2、数组的大小固定

    列表:1、元素的类型可以不一样;2、列表的大小不固定

    4、python中的列表是怎么存储的?

    栈:

    栈是一个数据集合,可以理解为智能在一端进行插入和删除操作的列表。

    栈的基本操作:进栈,出栈,取栈顶。

    栈的一个具体应用,括号匹配问题。

    代码:

    def bracket_match(string):
        bracket_dict = {")": "(", "]": "[", "}": "{", ">": "<"}
        li = []
        for item in string:
            if item in ["(","[","{","<"]:
                li.append(item)
            elif item in [")","]","}",">"]:
                if len(li) == 0:
                    print("多了右括号%s"%item)
                    return False
                elif li[-1] != bracket_dict[item]:
                    print("右括号和左括号不匹配")
                    return False
                elif li[-1] == bracket_dict[item]:
                    li.pop()
        if len(li) !=0:
            print("多了左括号")
            return False
        else:
            print("括号匹配")
            return True

     函数栈

    关于栈的一道面试题:

    进栈顺序为1,2,3;下面那个不可能是出栈顺序?

    A:1,2,3

    B:1,3,2

    C:2,1,3

    D:2,3,1

    E:3,2,1

    F:3,1,2

    F不可能

     栈的另外一个应用:

    迷宫问题:

    maze = [
        [1,1,1,1,1,1,1,1,1,1],
        [1,0,0,1,1,1,0,0,1,1],
        [1,0,0,0,0,1,1,0,0,1],
        [1,0,0,1,1,1,1,0,1,1],
        [1,0,0,0,0,0,0,0,0,1],
        [1,0,1,1,1,0,1,1,0,1],
        [1,0,1,1,1,0,1,1,0,1],
        [1,0,0,0,0,0,1,1,0,1],
        [1,1,1,1,1,0,0,0,0,1],
        [1,1,1,1,1,1,1,1,1,1]
            ]
    
    direction = [lambda x,y:(x,y-1),
     lambda x,y:(x+1,y),
     lambda x,y:(x,y+1),
     lambda x,y:(x-1,y)
     ]
    
    
    def find_path(x1,y1,x2,y2):
        """
        整体思想:向当前点的4个方向前进,如果前进方向上的点为0,则表示可以前进,找到一个方向就往前前进;如果一个点无法前进
        则回溯,直到回溯到能够前进的点,如果回溯到起点之后,stack中无值,则表示没有正确路径,或者找到正确路径输出正确路径。
        :param x1:起始点行坐标
        :param y1:起始点列坐标
        :param x2:终点行坐标
        :param y2:终点列坐标
        :return: True  or   False
        """
        # 初始化,起点终点和栈,将起点加到栈中,并设置起点为走过
        start = (x1,y1)
        end = (x2,y2)
        stack = []
        current = start
        stack.append(current)
        maze[current[0]][current[1]] = 2
        # 当当前节点不为终点时,执行循环,为终点则跳出循环打印路径
        while current != end:
            # 在4个方向上前进
            for d in direction:
                next_node = d(*current)
                # 前进的点值为0时
                if maze[next_node[0]][next_node[1]] == 0:
                    current = next_node
                    stack.append(current)
                    maze[current[0]][current[1]] = 2
                    # 4 个方向中有为0 的点,则for循环不会正常结束
                    break
            # 4个方向中没有为0的,则for循环正常结束,进入else中,栈pop掉当前节点,回溯到上一个节点继续循环
            else:
                stack.pop()
                if len(stack) == 0:
                    print("回溯超过起点,错误!无正确路径")
                    return False
                current = stack[-1]
        print(stack)
        return True
    
    
    # 另外一种写法
    def find_path_1(x1,y1,x2,y2):
        start = (x1,y1)
        end = (x2,y2)
        stack = []
        stack.append(start)
        while len(stack) > 0:
            current_node = stack[-1]
            if current_node == end:
                print("找到正确路径")
                print(stack)
                return True
            for d in direction:
                next_node = d(*current_node)
                if maze[next_node[0]][next_node[1]] == 0:
                    stack.append(next_node)
                    maze[next_node[0]][next_node[1]] = 2
                    # break 跳出,for循环的else也不执行
                    # 如果while正常执行完,则会执行else中的内容,如果遇到break跳出循环,则else中的内容也不会执行。
                    break
            else:
                stack.pop()
        print("回溯超过起点,没有正确路径")
        return False

    队列:

    队列是一个数据集合,仅允许在列表的一端进行插入,另外一端进行删除。

    队列用列表实现方式:

    环形队列,front指向队头,rear指向队尾。

    前进一步:front = (front + 1)%M;rear = (rear + 1)%M

    队满:(rear+1)%M == front%M

    队空·:rear%M == front%M

    python中队列:

    from collections import deque
    q = deque()  # 创建一个队列
    q.append(1)  # 往队列尾插入值
    print(q.popleft())  # 从队列左边出队
    q.appendleft(3)  # 往队列左边插入值
    print(q.pop())  # 从队列右边出队
    
    # 用队列实现tail功能
    q = deque([],5)
    for i in range(7):
        q.append(i)
    for i in range(5):
        print(q.popleft())
    
    q = deque(open("a.txt","rb"),5)
    for i in range(5):
        print(q.popleft().decode())

    链表:

    链表包含数据值和指向下一个节点的指针。

    手动创建链表:

    class Node(object):
        def __init__(self,item):
            self.item = item
            self.next = None
    
    a = Node(1)
    b = Node(2)
    c = Node(3)
    a.next = b
    b.next = c
    
    p = a
    while p != None:
        print(p.item)
        p = p.next

    链表与列表常见操作比较:

    按元素值查找,列表o(n),链表o(n),列表排序好后可以采用二分查找法,但是链表不行。

    按下标查找:列表o(1),链表o(n);

    在某元素后插入:列表o(n),链表o(1);

    删除某元素:列表o(n),链表o(1);

    链表现对于列表的优点

    1、在插入和删除操作,速度明显快于列表;

    2、使用链表,内存可以更加灵活的分布,可以利用链表重新实现栈和队列;

    3、链表的这种链式存储方式,对树和图的结构由明显的启发方式。

    建链表的两种方法和建好后再插入值,也可以用类实现;

    class Node(object):
        def __init__(self,item):
            self.item = item
            self.next = None
    # 建链表色两种方法
    # 1、头插法
    def create_linklist_head(li):
        head = None
        for i in li:
            p = Node(i)
            p.next = head
            head = p
        return head
    # 尾插法
    def create_linklist_tail(li):
        head = Node(li[0])
        tail = head
        for i in li[1:]:
            p = Node(i)
            tail.next = p
            tail =p
        return head
    def add_node_head(item,head):
        """
        头插法,增加节点
        :param item:需要增加节点的内容
        :param head:将节点添加到哪一个链表上
        :return:返回链表的头节点
        """
        p = Node(item)
        p.next = head
        head = p
        return head
    def add_node_tail(item,head):
        """
        尾插法增加一个节点,加在原链表的尾部
        :param item: 增加节点的内容
        :param head: 原链表的头节点
        :return: 原链表的头节点
        """
        p = Node(item)
        h = head
        while h.next != None:
            h = h.next
        h.next = p
        return head
    link_list_1 = create_linklist_head([1,2,3,4])
    link_list_1 = add_node_head(5,link_list_1)
    while link_list_1 != None:
        print(link_list_1.item)
        link_list_1 = link_list_1.next
    
    link_list_2 = create_linklist_tail([1,2,3,4])
    add_node_tail(5,link_list_2)  # 因为家在后面,所以不重新赋值也可以
    while link_list_2 != None:
        print(link_list_2.item)
        link_list_2 = link_list_2.next

    哈希表(散列表)

    通过哈希函数来计算数据存储位置的数据结构。

    python中,字典和集合都是通过hash表实现的。因此字典中的键是不可变类型,也就是可hash的,也就是能够映射的。

    数据库中的索引也可已用hash表

  • 相关阅读:
    Badboy录制脚本时,提示脚本错误解决方法
    Python数据类型_列表
    Wannafly Primary School Students训练记录
    Deadline队伍训练实录
    2018 German Collegiate Programming Contest (GCPC 18)
    2016ccpc杭州
    2016 ICPC 大连
    2017CCPC Final (哈尔滨)
    2017CCPC 长春
    2017 CCPC 杭州
  • 原文地址:https://www.cnblogs.com/zjsthunder/p/9788765.html
Copyright © 2011-2022 走看看