• 6.数据结构


    数据结构

    1.时间复杂度

    1.时间复杂度:大O表示 -- O(f(n))
    	量化算法需要的操作或者执行步骤的数量。
    2.基本操作执行次数的函数 T(n):
        如果T(n)=5n^2+27n+1005,随着 n 变大,n^2 这项变得越来越重要,我们可以忽略其他项,只关注5n^2,系数 5 也变得不重要。我们说,T(n) 具有的数量级为 f(n)=n^2,或者 O( n^2 )
    
    3.常见的时间复杂度比较:
    	O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)  < O(n!) < O(n^n)
    

    2.线性数据结构

    一.线性数据结构
    
      - 我们从四个简单但重要的概念开始研究数据结构。栈,队列,deques(双向队列), 列表是一类数据的容器,它们数据元素之间的顺序由添加或删除的顺序决定。一旦一个数据元素被添加,它相对于前后元素一直保持该位置不变。诸如此类的数据结构被称为线性数据结构。
    
      - 线性数据结构有两端,有时被称为左右,某些情况被称为前后。你也可以称为顶部和底部,名字都不重要。将两个线性数据结构区分开的方法是添加和移除元素的方式,特别是添加和移除元素的位置。例如一些结构允许从一端添加元素,另一些允许从另一端移除元素。
    

    栈 -- 先进后出,后进先出

    ​ 概念:栈(有时称为“后进先出栈”)是一个元素的有序集合,其中添加移除新元素总发生在同一端。这一端通常称为“顶部”。与顶部对应的端称为“底部”。栈的底部很重要,因为在栈中靠近底部的元素是存储时间最长的。最近添加的元素是最先会被移除的

    python实现栈:

    # 列表实现栈
    class Stack():
        # 创建一个空栈
        def __init__(self):
            self.items = []
        # 进栈添加数据 -- 追加数据
        def push(self,item):
            self.items.append(item)
        # 出栈移除数据 -- 从列表最后移除数据
        def pop(self):
            return self.items.pop()
        # 判断栈是否为空
        def isEmpty(self):
            return self.items == []
        # 栈长度
        def length(self):
            return len(self.items)
        
    # 测试:
    stack = Stack() # 实例化一个栈
    alist = [1,2,3,4]
    for item in alist:
    	stack.push(item)
    for i in range(stack.length()):
    	print(stack.pop()) # 4 3 2 1
    

    队列 -- 先进先出

    ​ 概念:队列是项的有序结合,其中添加新项的一端称为队尾,移除项的一端称为队首。当一个元素从队尾进入队列时,一直向队首移动,直到它成为下一个需要移除的元素为止。最近添加的元素必须在队尾等待。集合中存活时间最长的元素在队首,这种排序成为 FIFO,先进先出,也被成为先到先得。

    python实现队列:

    # 特性:先进先出
    # 入队列:从队尾部向头部添加
    # 出队列:从头部出队列
    class Queue():
        # 创建一个队列
    	def __init__(self):
    		self.items = []
        # 入队列
    	def enqueue(self,item):
    		self.items.insert(0,item)
        # 出队列
    	def dequeue(self):
    		return self.items.pop()
        # 判断队列是否为空
    	def isEmpty(self):
    		return self.items == []
        # 队列长度
    	def length(self):
    		return len(self.items)
        
    # 测试:
    queue = Queue() # 实例化一个队列
    alist = [1,2,3,4]
    for item in alist:
    	queue.enqueue(item)
    for i in range(queue.length()):
    	print(queue.dequeue())
    

    1.队列的应用案例-烫手的山芋

    烫手山芋游戏介绍:

    ​ 6个孩子围城一个圈,排列顺序孩子们自己指定。第一个孩子手里有一个烫手的山芋,需要在计时器计时1秒后将山芋传递给下一个孩子,依次类推。规则是,在计时器每计时7秒时,手里有山芋的孩子退出游戏。该游戏直到剩下一个孩子时结束,最后剩下的孩子获胜。请使用队列实现该游戏策略,排在第几个位置最终会获胜?

    分析: 循环报数,每到第6个人,剔除队列,直到只剩最后一人

    python代码实现:

    class Queue():
        def __init__(self):
            self.items = []
        # 进入队列
        def enqueue(self,item):
            self.items.insert(0,item)
        # 出队列
        def dequeue(self):
            return self.items.pop()
        # 判断是否为空
        def isEmpty(self):
            return self.items == []
        # 队列长度
        def length(self):
            return len(self.items)
    
    # 实例化一个队列对象
    queue = Queue()
    # 孩子列表
    kids = list(range(1,7))
    print(kids)
    # 添加到队列
    for i in kids:
        queue.enqueue(i)
        
    # 循环移除队列,直到剩最后一人
    while queue.length() > 1:
        for i in range(6):
            # 队列循环
            item = queue.dequeue()
            queue.enqueue(item)
        # 移除第6个孩子
        queue.dequeue()
    
    print('最后获胜者:',queue.dequeue())
    

    2.两个队列实现一个栈的效果

    # 队列 先进先出 --> 栈 后进先出
    class Queue():
        def __init__(self):
            self.items = []
        # 进入队列
        def enqueue(self,item):
            self.items.insert(0,item)
        # 出队列
        def dequeue(self):
            return self.items.pop()
        # 判断是否为空
        def isEmpty(self):
            return self.items == []
        # 队列长度
        def length(self):
            return len(self.items)
    
    # 实例化两个队列
    q1 = Queue()
    q2 = Queue()
    lis = [1,2,3,4]
    # 入队列
    for i in lis:
        q1.enqueue(i)
        
    # 循环终止条件
    while q1.length() > 0:
        for i in range(q1.length()-1):
            item = q1.dequeue()
            q2.enqueue(item)
        print(q1.dequeue())
        # 队列交换
        q1,q2 = q2,q1
    
    

    3.两个栈实现一个队列效果

    # 栈 后进先出 --> 队列 先进先出
    class Stack():
        def __init__(self):
            self.items = []
        # 进栈
        def push(self,item):
            self.items.append(item)
        # 出栈
        def pop(self):
            return self.items.pop()
        # 判断是否为空
        def isEmpty(self):
            return self.items == []
        # 栈长度
        def length(self):
            return len(self.items)
    
    # 实例化两个栈对象
    s1 = Stack()
    s2 = Stack()
    lis = [1,2,3,4]
    # 添加栈
    for i in lis:
        s1.push(i)
    
    # 改变栈顺序 -- 后进先出
    for i in range(s1.length()):
        item = s1.pop()
        s2.push(item)
        
    # 循环遍历s2
    for i in range(s2.length()):
        print(s2.pop())
    

    双端队列

    特性: 可以从任意端(队首,队尾)添加,也可以从任意端移除

    python代码实现:

    class Deque():
        # 创建一个空队列
        def __init__(self):
            self.items = []
        # 从前边入队列
        def add_front(self,item):
            self.items.insert(0,item)
        # 从后边入队列
        def add_rear(self,item):
            self.items.append(item)
        # 从前边移除队列
        def remove_front(self):
            return self.items.pop(0)
        # 从后边移除队列
        def remove_rear(self):
            return self.items.pop()
        # 判断队列是否为空
        def is_empty(self):
            return self.items == []
        # 队列长度
        def length(self):
            return len(self.items)
    

    回文检索 -- 设计程序,检测一个字符串是否为回文

    回文:回文是一个字符串,读取首尾相同的字符,例如,radar toot madam

    # 回文检索
    def jiance(str):
        # 实例化双端队列对象
        deque = Deque()
        # 添加队列
        for i in str:
            deque.add_rear(i)
        # 判断是否是回文
        is_huiwen = True
    
        while (deque.length() > 1) and is_huiwen:
            # 首字符
            front = deque.remove_front()
            # 尾字符
            rear = deque.remove_rear()
            # 判断首尾字符是否相等
            if front != rear:
                is_huiwen = False
    
        return is_huiwen
    
    # 测试
    str = 'radar'
    print(jiance(str)) # True
    
    

    3.链表

    ​ 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是每一个结点(数据存储单元)里存放下一个结点的信息(即地址)

    单向链表

    ​ 单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接域指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

    python代码实现:

    # 封装节点
    class Node():
        def __init__(self,item):
            self.item = item # 元素域
            self.next = None # 连接域
    
    # 封装链表
    class Link():
        # 1.链表的头
        def __init__(self):
            self._head = None
            
        # 2.判断链表是否为空
        def is_empty(self):
            return self._head is None
        
        # 3.链表长度
        def length(self):
            cur = self._head
            count = 0
            while cur:
                count += 1
                cur = cur.next
            return count
        
        # 4.向链表头部添加节点元素
        def add_front(self,item):
            node = Node(item)
            node.next = self._head
            self._head = node
            
        # 5.向链表尾部添加节点元素
        def add_rear(self,item):
            node = Node(item)
            cur = self._head
            # 判断是否为空链表
            if self.is_empty():
                node.next = self._head
                self._head = node
                return
            # 循环链表找到最后一个节点元素
            while cur:
                pre = cur
                cur = cur.next
            node.next = None
            pre.next = node
            
        # 6.遍历链表
        def trasersal(self):
            if self.is_empty():
                print('链表中没有数据')
                return  # 终止程序
            # 表头位置不要动,重新赋值
            cur = self._head
            while cur:
                print(cur.item)
                cur = cur.next
                
        # 7.查找节点元素是否存在
        def search(self,item):
            cur = self._head
            # 判断是否为空链表
            if cur is None:
                return False
            while cur:
                if cur.item == item:
                    return True
                cur = cur.next
            return False
    
        # 8.指定位置添加元素
        def add_index(self,pos,item):
            node = Node(item)
            if pos > self.length():
                print('超出链表索引位置,不能添加')
                return # 终止程序
            if pos == 0: # 从头添加
                node.next = self._head
                self._head = node
            sum = 1 # 当前链表位置
            cur = self._head
            while cur:
                pre = cur
                cur = cur.next
                if pos == sum:
                    pre.next = node
                    node.next = cur
                sum += 1
    
        # 9.删除链表节点元素
        def remove(self,item):
            pre = None # cur前一个节点
            cur = self._head
            while cur:
                if cur.item == item:
                    if pre is None: # 删除的是第一个节点元素
                        self._head = cur.next
                        return # 终止程序
                    pre.next = cur.next # 删除非第一个节点元素
                pre = cur
                cur = cur.next
            print('链表中没有你要删除的元素')
            
        # 10.反转链表
        def reverse(self):
            if self.is_empty():
                print('链表中没有数据,不能反转')
                return
            pre = None # 前一个节点
            cur = self._head # 当前节点
            nex = cur.next # 后一个节点
            while cur:
                cur.next = pre # 当前节点的下一个节点是前一个节点
                pre = cur
                cur = nex
                if cur is not None:
                    nex = nex.next
            self._head = pre # 最后,把链表头放到链表最后一个节点
    
    # 测试
    # 实例化链表对象
    link = Link()
    
    print(link.is_empty())
    link.trasersal()
    link.add_front(1)
    link.add_front(2)
    link.add_rear(66)
    print(link.search(2))
    link.add_index(5,66)
    link.remove(66)
    link.reverse()
    link.trasersal()
    
    print(link.length())
    
    
    
  • 相关阅读:
    Excel的VBA小练习
    敏捷和产品
    Ubuntu的系统应用
    也晒晒生产力工具:键盘
    SQLServer 2012 Ent 安装失败,另辟蹊径
    还是要精简开发呀,VS2015太大,VS2010不想装
    必须夸夸Sublime,大文件打开
    过节了,开源中国歪歪了!!!
    关于VisualStudio2010发布项目问题
    Visual Studio 各个版本汇总
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14716058.html
Copyright © 2020-2023  润新知