基础数据结构的python实现----队列、栈、链表、二叉树

基础数据结构的python实现----队列、栈、链表、二叉树

1 队列-Queue

#队列:先进先出
class Queue():
    def __init__(self):
        self.items = []
     
    #进入队列
    def enqueue(self, item):
        self.items.append(item)
        
    #出队列
    def dequeue(self):
        return self.items.pop(0)
    
    #遍历队列元素
    def travel(self):
        for i in self.items:
            print(i)
            
    #获取队列长度
    def size(self):
        count = 0
        for i in self.items:
            count += 1
        return count
        

queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
queue.enqueue(4)
queue.travel()

2 栈-Stack

#栈堆: 先进后出
class Stack():
    def __init__(self):
        self.items = []
     
    #进入队列
    def enstack(self, item):
        self.items.append(item)
        
    #出队列
    def destack(self):
        return self.items.pop()
    
    #遍历栈元素
    def travel(self):
        lenth = len(self.items)
        for i in range(lenth):
            print(self.items[lenth - i - 1])

stack = Stack()
stack.enstack(1)
stack.enstack(2)
stack.enstack(3)
stack.enstack(4)
stack.destack()
stack.travel()
2.1 两个队列实现一个栈

两个队列实现栈。获取两个,queue1 和 queue2。

  • 进栈:都将数据输入queue1中;
  • 出栈:将queue1的除了最后一个数据之外的都转移到queue2中,输出queue1的剩下的元素,即出栈;
  • queue1 和 queue2交换。
#用两个队列实现一个栈
class MyStack():
    
    def __init__(self):
        #初始化两个queue
        self.queue1 = Queue()
        self.queue2 = Queue()
     
    #进栈
    def Enstack(self, item):
        self.queue1.enqueue(item)
      
    #出栈    
    def Destack(self):
        
        if self.size() == 1:
            return self.queue1.dequeue()
            
        if self.size() > 1:
    
            while self.size() > 1:
                item = self.queue1.dequeue()
                self.queue2.enqueue(item)
            
            self.queue1 , self.queue2 = self.queue2, self.queue1
            
            return self.queue2.dequeue()

    def size(self):
        return self.queue1.size()
    
    #遍历栈
    def travel(self):
        for i in range(self.size()):
            print(self.Destack())
        
 
mystack = MyStack()
mystack.Enstack(1)
mystack.Enstack(2)
mystack.Enstack(3)
mystack.Enstack(4)
mystack.Enstack(5)
mystack.travel()

'''
output:
5
4
3
2
1
'''
#做到了先进后出

队列(queue)和栈(stack)表示在内存中,都是开辟的一整块连续的空间,对应查找比较方便:时间复杂度O(1);但是增删比较麻烦,时间复杂度为O(n)。

3 链表-Link

单向链表相比队列和栈,每个数据节点多了一个指针,指向下一个节点的地址。因此链表的内存空间并不是连续的开辟的一块,而是离散分布的一个个小节点内存块,批次通过指针连接起来。对应的增删比较方便,时间复杂度为O(1),查找麻烦,时间复杂度为O(n)。

3.1 单向链表
#先定义节点,每个节点Node包含两个属性:数据(item) + 地址指针(next)
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):
        #从头节点开始,当节点不为空,则继续next
        node = self._head
        while node:
            print(node.item)
            node = node.next
    
    #是否为空
    def isEmpty(self):
        return False if self._head else True
    
    #有多少个节点
    def size(self):
        count = 0 
        node = self._head
        while node:
            count = count + 1
            node = node.next
        return count
    
    #向链表尾部添加一个Node
    def append(self, item):
        node = Node(item)
        
        #当链表为空时
        if self.isEmpty():
            self._head = node
        
        #当链表不为空时
        else:
            pre = None
            cur = self._head
            while cur: 
                pre = cur
                cur = cur.next
            
            pre.next = node
    
    #search指定item在链表中哪个位置,返回一个位置list,如果没有,则为空列表
    def search(self, item):
        indexs = []
        count = 0
        node = self._head
        while node:
            if item == node.item:
                indexs.append(count)
            count = count + 1
            node = node.next
        
        if len(indexs) == 0:
            print(False)
            return None
        else:
            print(True)
            return indexs
        
    #在指定位置插入节点   
    def insert(self, index, item):
        #确定要插入的位置坐标是否大于原有链表长度
        ori_size = self.size()
        if index > ori_size:
            print('index out of link range!')
            
        else:    
            if index == 0 or ori_size == 0:
                self.add(item)
            elif index == ori_size:
                self.append(item)
            else:
                node = Node(item)
                pre = self._head
                for i in range(1,index):
                    pre = pre.next()
                
                node.next = pre.next
                pre.next = node
    
    #移除指定位置的节点
    def remove_index(self, index):
        
        if index == 0:
            self._head = self._head.next
            
        else:
            pre = None
            cur = self._head
            for i in range(index):
                pre = cur
                cur = cur.next
            
            pre.next = cur.next
            
    #移除指定数值的所有节点     
    def remove_item(self, item):
        
        #先获取该item在链表中的所有indexs, 之后挨个删除
        indexs = self.search(item)
        if len(indexs) == None:
            print('item not in link')
            return False
        
        else:
            count = 0
            for index in indexs:
                index = index - count
                self.remove_index(index)
                count += 1
    
    #链表反向排序    
    def reverse(self):
        pre = None
        cur = self._head
        next_node = cur.next
        while cur:
            cur.next = pre
            pre = cur
            cur = next_node
            if cur:
                next_node = cur.next
            else:
                break
            
        self._head = pre
            
    
link = Link()
link.append(4)
link.add(3)
link.add(5)
link.append(8)
link.add(10)
link.travel()

'''
output:
10
5
3
4
8
'''
3.2 双向链表

双向链表相比单向链表多了一个指向上一个节点的地址的指针。

#双链表
class Node():
    #定义节点的头和尾
    def __init__(self, item):
        self.item = item
        self.head = None
        self.next = None
        
        
class DoubleLink():
    
    def __init__(self):
        self._head = None
    
    #在头部节点插入
    def add(self, item):
        node = Node(item)
        node.next = self._head
        self._head = node
        
    
    #在尾部节点插入
    def append(self, item):

        if self.size() == 0:
            self.add(item)
           
        else:
            node = Node(item)
            
            pre = None
            cur = self._head
            while cur:
                pre = cur
                cur = cur.next
            pre.next = node
            node.head = pre
        
    #在某个index出插入
    def insert(self, index, item):
        
        ori_size = self.size()
        if ori_size == 0 or index == 0:
            self.add(item)
        elif ori_size == index:
            self.append(item)
        else:
            node = Node(item)
            
            pre = None
            cur = self._head
            
            for i in range(0,index):
                pre = cur
                cur = cur.next
                
            cur.head = node
            node.next = cur
            
            node.head = pre
            pre.next = node

        
    def travel(self):
        cur = self._head
        while cur:
            print(cur.item)
            cur = cur.next
        
  
    def size(self):
        count = 0
        cur = self._head
        while cur:
            cur = cur.next
            count += 1
        return count

        
doublelink = DoubleLink()
doublelink.append(1)
doublelink.append(2)
doublelink.append(3)
doublelink.append(4)
doublelink.insert(2,5)
doublelink.travel()   

'''
output:
1
2
5
3
4
'''

4 二叉树 + 广度(深度)优先节点遍历

二叉树是一种常见的树形数据结构,进一步了解可参考:数据结构和算法(十):二叉树

4.1 普通二叉树
#定义节点,每个节点有3个属性:数值 + 左指针 + 右指针
class Node():
    def __init__(self,item):
        self.item = item
        self.left = None
        self.right = None
        
#定义一个二叉树
class Tree():
    def __init__(self):
        self.root = None
    
    #向树中添加节点:按层从左到右顺序插入
    def add_node(self, item):
        
        node = Node(item)
        
        #无节点存在,则插入根节点
        if self.root == None:
            self.root = node
            
        else:
            List = [self.root]
            while List:
                q = List.pop(0)
                if q.left == None:
                    q.left = node
                    break
                else:
                    List.append(q.left)
                if q.right == None:
                    q.right = node
                    break
                else:
                    List.append(q.right)
                    
    #遍历树,按照添加节点顺序输出节点数值: 按层从左到右遍历 --- 广度优先遍历
    def BFS_travel(self):
        List = [self.root]
        while List:
            q = List.pop(0)
            print(q.item)
            if q.left != None:
                List.append(q.left)
            if q.right != None:
                List.append(q.right)
    
    #遍历树:深度优先算法:前序遍历 --根左右
    def DFS_Forward(self, root):
        if root != None:
            print(root.item)
            self.DFS_Forward(root.left)
            self.DFS_Forward(root.right)
    
    #深度优先算法:中序遍历 --左根右
    def DFS_Middle(self, root):
        if root != None:
            self.DFS_Middle(root.left)
            print(root.item)
            self.DFS_Middle(root.right)
            
    #深度优先算法:后序遍历 --左右根       
    def DFS_Backward(self, root):
        if root != None:
            self.DFS_Backward(root.left)
            self.DFS_Backward(root.right)
            print(root.item)
            
tree = Tree()
tree.add_node(1)
tree.add_node(2)
tree.add_node(3)
tree.add_node(4)
tree.add_node(5)
tree.add_node(6)
tree.add_node(7)
tree.add_node(8)
tree.BFS_travel()

'''
output: 1 2 3 4 5 6 7 8
'''
4.2 排序二叉树
#排序二叉树
class SortedTree():
    def __init__(self):
        self.root = None
    
    #添加节点时:大于根节点的在右子节点,大小等于根节点的在左子节点
    def add_node(self, item):
        node = Node(item)
        if self.root == None:
            self.root = node
        else:
            cur = self.root
            while True:
                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 BFS_travel(self):
        List = [self.root]
        while List:
            q = List.pop(0)
            print(q.item)
            if q.left != None:
                List.append(q.left)
            if q.right != None:
                List.append(q.right)
    
    #遍历树:深度优先算法:前序遍历 --根左右
    def DFS_Forward(self, root):
        if root != None:
            print(root.item)
            self.DFS_Forward(root.left)
            self.DFS_Forward(root.right)
    
    #深度优先算法:中序遍历 --左根右
    def DFS_Middle(self, root):
        if root != None:
            self.DFS_Middle(root.left)
            print(root.item)
            self.DFS_Middle(root.right)
            
    #深度优先算法:后序遍历 --左右根       
    def DFS_Backward(self, root):
        if root != None:
            self.DFS_Backward(root.left)
            self.DFS_Backward(root.right)
            print(root.item)
            
sortedTree =  SortedTree()
sortedTree.add_node(3)
sortedTree.add_node(8)
sortedTree.add_node(5)
sortedTree.add_node(7)
sortedTree.add_node(6)
sortedTree.add_node(2)
sortedTree.add_node(9)
sortedTree.add_node(4)
sortedTree.add_node(1)
print('DFS_Forward:')
sortedTree.DFS_Forward(sortedTree.root)
print('DFS_Middle:')
sortedTree.DFS_Middle(sortedTree.root)
print('DFS_Backward:')
sortedTree.DFS_Backward(sortedTree.root)

'''
output:
DFS_Forward: 3 2 1 8 5 4 7 6 9
DFS_Middle:  1 2 3 4 5 6 7 8 9
DFS_Backward: 1 2 4 6 7 5 9 8 3
'''

使用排序二叉树存储节点时,中序排列的结果一定为:递增的数组。

End:重温数据结构。后续将跟进对一些算法的理解和实现。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值