数据结构 栈 队列 顺序表 链表 二叉树 排序二叉树

算法:对问题进行处理且求解的一种思路或者思想

时间复杂度:量化算法执行的操作执行步骤的数量,最重要的项,采用大O记法

数据结构:对于基本数据的组织方式

python数据结构性能分析:

from timeit import Timer
def test01():
    alist = []
    for i in range(1000):
        alist = [i]
    return alist

def test02():
    alist = []
    for i in range(1000):
        alist.appned(i)
    return alist

def test03():
    return [i for i in range(1000)]

def test04():
    alist = list(range(1000))
    return alist

if __name__=="__main__":
    timer1 = Timer("test01()",'from __main__ import test01')
    t1 = timer1.timeit(10000)
    timer2 = Timer("test02",'from __main__ import test02')
    t2 = timer2.timeit(10000)
    timer3 = Timer("test03",'from __main__ import test03')
    t3 = timer3.timeit(10000)
    timer4 = Timer("test04",'from __main__ import test04')
    t4 = timer4.timeit(10000)
    print(t1,t2,t3,t4)

特性:先进后出的数据结构

# 自定义一个栈类
class Stack():
	def __init__(self):
        self.items = []
    def enqueue(self,item):		# 入栈
        self.items.append(item)
    def dequeue(self):			# 出栈
        return self.items.pop()
    def peek(self):				# 返回栈的顶部项
        return len(self.items)-1
    def isEmpty(self):			# 判断是否为空
        return self.items == []
    def size(self):				# 判断栈的元素个数
        return len(self.items)

队列

特性:先进先出

案例:烫手的山芋

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

#! -*- encode: utf-8 -*-
# 准则:手里有山芋的孩子永远排在队列的头部
# 自定义一个队列类
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 size(self):				# 判断元素个数
        return len(self.items)
    
kids = ["A","B","C","D","E","F"]
queue = Queue()
for kid in kids:
    queue.enqueue(kid)			# A对尾 F队尾
while queue.size() > 1:
    for i in range(6):			# 传递次数
        kid = queue.dequeue()	#  让队头元素先出队列
        queue.enqueue(kid)		# 再入队列,保持拿芋头的人在队头
    queue.dequeue()				# 一次计时结束,删除队头的人
print("获胜的选手是:",queue.dequeue())

双端队列

特性:有两个头部和尾部,可以在双端进行数据的插入和删除,提供了单数据结构中栈和队列的特性

案例:实现回文检查

#! -*- encode: utf-8 -*-
# 自定义双端队列类
class Deque():
    def __init__(self):
        self.items = []
    def addFront(self,item):	# 首部添加元素
        self.items.insert(0,item)
    def addRear(self,item):		# 尾部添加元素
        self.items.append(item)
    def removeFront(self):		# 删除首部元素
        return self.items.pop()
    def removeRear(self):		# 删除尾部元素
        return self.items.pop(0)
    def isEmpty(self):			# 判断是否为空
        return self.items == []
    def size(self):				# 判断元素个数
        return len(self.items)
    
def isHuiWen(s):
    deque = Deque()
    for i in str(s):
        deque.addRear(i)
    while deque.size() > 0:
        if deque.removeFront() != deque.removeRear():
            res = False
            break
        else:
            res = True
    return res
    
print(isHuiWen(12345321))

面试题:如何用两个队列形成一个栈

# 自定义一个队列类
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 size(self):				# 判断元素个数
        return len(self.items)
    def travel(self):
        for item in self.items:
            print(item)
    
alist = ["1","2","3","4","5"]
queue = Queue()
for i in alist:
    queue.enqueue(i)

def toStack(queue):
    queue2 = Queue()
    while queue.size() > 0:
        while True:
            item = queue.dequeue()
            if queue.size() == 0:
                print(item)
                break
            queue2.enqueue(item)
            if queue.size() <= 1:
                print(queue.dequeue())
                break
        queue,queue2 = queue2,queue
        
toStack(queue)

顺序表

集合中存储的元素是有顺序的,顺序表的结构分为单数据类型和多数据类型

列表和元组属于多数据类型的顺序表 一个整型占据的内存占四个字节

单数据类型:内存空间连续开辟,数据类型统一

多数据类型顺序表:内存非连续开辟,同时会开辟一个单独的内存空间来存放非连续内存空间的地址

弊端:顺序表的结构需要预先知道数据大小来申请连续的存储空间,而在扩充时又需要进行数据的搬迁

链表

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

相对于顺序表,链表结构可以充分利用计算机内存空间,实现灵活的动态内存管理且进行扩充时不需要进行数据搬迁

class Node():
    def __init__(self,item):
        self.item = item
        self.next = None

class Link():
    def __init__(self):
        # 构造出一个空的列表
        # 且_head只能为空或者第一个结点的地址
        self._head = None
    # 向链表的头部添加一个结点
    def add(self,item):
        # 创建一个新的结点
        node = Node(item)
        # 先把之前数据的地址传递到新插入数据的next属性中
        node.next = self._head
        # 将新数据的地址赋值给_head属性,这样就成功插入到了头部
        self._head = node
    # 链表的遍历
    def travel(self):
        # _head 在链表创建好后一定是不可变的,一旦变化,链表随之改变
        cur = self._head
        while cur:		# 当cur为None时,结束遍历
            print(cur.item)
            cur = cur.next
    # 链表的长度
    def size(self):
        cur = self._head
        count = 0
        while cur:
            count += 1
            cur = cur.next
        return count
    # 向链表的尾部添加
    def append(self,item):
        node = Node(item)
        # 需要做一个链表为空的判断
        if self._head == None:
            self._head = node
            return
        cur = self._head
        # 判断前一个是否为末端,如果不是则继续往前取值
        while cur.next:
            cur = cur.next
        cur.next = node
        
    # 查找
    def search(self,item):
        cur = self._head
        while cur:
            if cur.item = item:
                find = True
                break
            else:
            	cur = cur.next
                find = False
        return find
    
    # 定向插入
    def insert(self,pos,item):
        if pos == 0 or pos > self.size():
            print('插入的位置有误')
            return
        node = Node(item)
        pre = None
        cur = self._head
        for i in range(pos):
            pre = cur 
            cur = cur.next
        pre.next = node
        node.text = cur
        
    # 定向删除
    def remove(self,item):
        cur = self._head
        pre = None
        while cur :
            if cur.item == item:
                pre.next = cr.next
                return
            pre = cur
            cur = cur.next
            
        # 链表倒置
    def reverse(self):
        cur = self._head
        pre = None
        nex = cur.next
        if cur == None:
            print('列表为空')
        while cur:
            cur.next = pre
            pre = cur
            cur = nex
            if cur:
                nex = cur.next
            
        self._head = pre
        return

二叉树

根节点

叶子节点:左叶子结点 右叶子结点

数的层级/数的高度

class Node():
    def __init__(self,item):
        self.item = item
        self.left = None
        self.right = None


class Tree():
    def __init__(self):
        self.root = None
    
    def addNode(self,item):
        node = Node(item)
        # 如果插入第一个结点的情况
        if self.root == None:
            self.root = node
            return
        cur = self.root
        q = [cur]       # 列表元素使我们遍历判断的结点
        
        while q:
            nd = q.pop(0)
            if nd.left == None:
                nd.left = node
                return
            else:
                q.append(nd.left)
            if nd.right == None:
                nd.right = node
                return
            else:
                q.append(nd.right)

    def travel(self):
        cur = self.root
        q = [cur]
        while q:
            nd = q.pop(0)
            print(nd.item)
            if nd.left:
                q.append(nd.left)
            if nd.right:
                q.append(nd.right)
    # 深度遍历:前序        
    def forward(self,root):
        if root == None:
            return
        print(root.item)
        self.forward(root.left)
        self.forward(root.right)
    # 深度遍历:中序        
    def middle(self,root):
        if root == None:
            return
        self.middle(root.left)
        print(root.item)
        self.middle(root.right)
    # 深度遍历:后序        
    def back(self,root):
        if root == None:
            return
        self.back(root.left)
        self.back(root.right)    
        print(root.item)
二叉树的遍历

广度优先遍历:一层一层对结点进行遍历

深度优先遍历:

前序:根左右 1 2 4 5 3 6 7

中序:左根右 4 2 5 1 6 3 7

后序:左右根 4 5 2 6 7 3 1

排序二叉树

乱序数据的插入的时候,需要遵从一个准则:

​ 插入的第一个数值作为树的根节点

​ 乱序插入的数值,如果比根节点小,插入根节点的左侧,否则插入到根节点的右侧

# 排序二叉树
class Node():
    def __init__(self,item):
        self.item = item
        self.left = None
        self.right = None


class SortTree():
    def __init__(self):
        self.root = None
        
    def add(self,item):
        node = Node(item)
        cur = self.root
        if self.root == None:
            self.root = node
            return
        while cur:
            # 右侧插入
            if item > cur.item:
                if cur.right == None:
                    cur.right = node
                    break
                else:
                    cur = cur.right
            else:   # 左侧插入
                if cur.left == None:
                    cur.left = node
                    break
                else:
                    cur = cur.left
    

    # 深度遍历:中序        
    def middle(self,root):
        if root == None:
            return
        self.middle(root.left)
        print(root.item)
        self.middle(root.right)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值