常见数据结构的 Python 实现(建议收藏)

简介: 数据结构作为计算机基础的必修内容,也是很多大型互联网企业面试的必考题。可想而知,它在计算机领域的重要性。然而很多计算机专业的同学,都仅仅是了解数据结构的相关理论,却无法用代码实现各种数据结构。栈class Stack(object): def __init__(self, limit=10): self.

数据结构作为计算机基础的必修内容,也是很多大型互联网企业面试的必考题。可想而知,它在计算机领域的重要性。

然而很多计算机专业的同学,都仅仅是了解数据结构的相关理论,却无法用代码实现各种数据结构。

class Stack(object):
    def __init__(self, limit=10):
        self.stack = [] #存放元素
        self.limit = limit #栈容量极限
    def push(self, data): #判断栈是否溢出
        if len(self.stack) >= self.limit:
            print('StackOverflowError')
            pass
        self.stack.append(data)
    def pop(self):
        if self.stack:
            return self.stack.pop()
        else:
            raise IndexError('pop from an empty stack') #空栈不能被弹出
    def peek(self): #查看堆栈的最上面的元素
        if self.stack:
            return self.stack[-1]
    def is_empty(self): #判断栈是否为空
        return not bool(self.stack)
    def size(self): #返回栈的大小
        return len(self.stack)

单链表

class Node:  
    def __init__(self, data):
        self.data = data  
        self.next = None  
class Linked_List:
    def __init__(self):
        self.head = None
    def initlist(self,data_list):    #链表初始化函数
        self.head=Node(data_list[0])   #创建头结点
        temp=self.head
        for i in data_list[1:]: #逐个为 data 内的数据创建结点, 建立链表
            node=Node(i)
            temp.next=node
            temp=temp.next #
    def is_empty(self):  #判断链表是否为空
        if self.head.next==None:
            print("Linked_list is empty")
            return True
        else:
            return False
    def get_length(self):  #获取链表的长度
        temp=self.head #临时变量指向队列头部
        length=0 #计算链表的长度变量
        while temp!=None:
            length=length+1
            temp=temp.next
        return length #返回链表的长度
    def insert(self,key,value): #链表插入数据函数
        if key<0 or key>self.get_length()-1:
            print("insert error")
        temp=self.head
        i=0
        while i<=key: #遍历找到索引值为 key 的结点后, 在其后面插入结点
            pre=temp
            temp=temp.next
            i=i+1
        node=Node(value)
        pre.next=node
        node.next=temp
    def print_list(self):   #遍历链表,并将元素依次打印出来
        print("linked_list:")
        temp=self.head
        new_list=[]
        while temp is not None:
            new_list.append(temp.data)
            temp=temp.next
        print(new_list)
    def remove(self,key):  #链表删除数据函数
        if key<0 or key>self.get_length()-1:
            print("insert error")
        i=0
        temp=self.head
        while temp !=None:  #遍历找到索引值为 key 的结点
            pre=temp
            temp=temp.next
            i=i+1
            if i==key:
                pre.next=temp.next
                temp=None
                return True
        pre.next=None
    def reverse(self): #将链表反转
        prev = None
        current = self.head
        while current:
            next_node = current.next
            current.next = prev
            prev = current
            current = next_node
        self.head = prev

双链表

class Node(object):
    # 双向链表节点
    def __init__(self, item):
        self.item = item
        self.next = None
        self.prev = None
class DLinkList(object):
    # 双向链表
    def __init__(self):
        self._head = None
    def is_empty(self):
        # 判断链表是否为空
        return self._head == None
    def get_length(self):
        # 返回链表的长度
        cur = self._head
        count = 0
        while cur != None:
            count=count+1
            cur = cur.next
        return count
    def travel(self):
        # 遍历链表
        cur = self._head
        while cur != None:
            print(cur.item)
            cur = cur.next
        print("")
    def add(self, item):
        # 头部插入元素
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 将node的next指向_head的头节点
            node.next = self._head
            # 将_head的头节点的prev指向node
            self._head.prev = node
            # 将_head 指向node
            self._head = node
    def append(self, item):
        # Python学习交流QQ群:857662006 
        # 尾部插入元素
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 移动到链表尾部
            cur = self._head
            while cur.next != None:
                cur = cur.next
            # 将尾节点cur的next指向node
            cur.next = node
            # 将node的prev指向cur
            node.prev = cur
    def search(self, item):
        # 查找元素是否存在
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False
    def insert(self, pos, item):
        # 在指定位置添加节点
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 移动到指定位置的前一个位置
            while count < (pos-1):
                count += 1
                cur = cur.next
            # 将node的prev指向cur
            node.prev = cur
            # 将node的next指向cur的下一个节点
            node.next = cur.next
            # 将cur的下一个节点的prev指向node
            cur.next.prev = node
            # 将cur的next指向node
            cur.next = node
    def remove(self, item):
        # 删除元素
        if self.is_empty():
            return
        else:
            cur = self._head
            if cur.item == item:
                # 如果首节点的元素即是要删除的元素
                if cur.next == None:
                    # 如果链表只有这一个节点
                    self._head = None
                else:
                    # 将第二个节点的prev设置为None
                    cur.next.prev = None
                    # 将_head指向第二个节点
                    self._head = cur.next
                return
            while cur != None:
                if cur.item == item:
                    # 将cur的前一个节点的next指向cur的后一个节点
                    cur.prev.next = cur.next
                    # 将cur的后一个节点的prev指向cur的前一个节点
                    cur.next.prev = cur.prev
                    break
                cur = cur.next

队列(链表形式实现)

class Node(object):
    def __init__(self,elem,next=None):
        self.elem = elem #表示对应的元素值
        self.next=next #表示下一个链接的链点
class Queue(object):
    def __init__(self):
        self.head = None #头部链点为 None
        self.rear = None #尾部链点为 None
    def is_empty(self):
        return self.head is None #判断队列是否为空
    def enqueue(self, elem):
        p = Node(elem) #初始化一个新的点
        if self.is_empty(): #Python学习交流QQ群:857662006 
            self.head = p #队列头部为新的链点
            self.rear = p #队列尾部为新的链点
        else:
            self.rear.next = p #队列尾部的后继是这个新的点
            self.rear =p #然后让队列尾部指针指向这个新的点
    def dequeue(self):
        if self.is_empty(): #判断队列是否为空
            print('Queue_is_empty') #若队列为空,则退出 dequeue 操作
        else:
            result = self.head.elem #result为队列头部元素
            self.head = self.head.next #改变队列头部指针位置
            return result #返回队列头部元素
    def peek(self):
        if self.is_empty(): #判断队列是否为空
            print('NOT_FOUND') #为空则返回 NOT_FOUND
        else:
            return self.head.elem #返回队列头部元素
    def print_queue(self):
        print("queue:")
        temp=self.head
        myqueue=[] #暂时存放队列数据
        while temp is not None:
            myqueue.append(temp.elem)
            temp=temp.next
        print(myqueue)

队列(数组形式实现)

class Queue():
    def __init__(self):
        self.entries = [] #表示队列内的参数
        self.length = 0 #表示队列的长度
        self.front=0 #表示队列头部位置
    def enqueue(self, item):
        self.entries.append(item) #添加元素到队列里面
        self.length = self.length + 1 #队列长度增加 1
    def dequeue(self):
        self.length = self.length - 1 #队列的长度减少 1
        dequeued = self.entries[self.front] #队首元素为dequeued
        self.front-=1 #队首的位置减少1
        self.entries = self.entries[self.front:] #队列的元素更新为退队之后的队列
        return dequeued
    def peek(self):
        return self.entries[0] #直接返回队列的队首元素

二叉树

class Node(object):
    def __init__(self,item):
        self.item=item #表示对应的元素
        self.left=None #表示左节点
        self.right=None #表示右节点
    def __str__(self):
        return str(self.item)  #print 一个 Node 类时会打印 __str__ 的返回值
class Tree(object): #Python学习交流QQ群:857662006 
    def __init__(self):
        self.root=Node('root')  #根节点定义为 root 永不删除,作为哨兵使用。
    def add(self,item):
        node = Node(item)
        if self.root is None:  #如果二叉树为空,那么生成的二叉树最终为新插入树的点
            self.root = node
        else:
            q = [self.root] # 将q列表,添加二叉树的根节点
            while True:
                pop_node = q.pop(0)
                if pop_node.left is None: #左子树为空则将点添加到左子树
                    pop_node.left = node
                    return
                elif pop_node.right is None: #右子树为空则将点添加到右子树
                    pop_node.right = node
                    return
                else:
                    q.append(pop_node.left)
                    q.append(pop_node.right)
    def get_parent(self, item):
        if self.root.item == item:
            return None  # 根节点没有父节点
        tmp = [self.root] # 将tmp列表,添加二叉树的根节点
        while tmp:
            pop_node = tmp.pop(0)
            if pop_node.left and pop_node.left.item == item: #某点的左子树为寻找的点
                return pop_node #返回某点,即为寻找点的父节点
            if pop_node.right and pop_node.right.item == item: #某点的右子树为寻找的点
                return pop_node #返回某点,即为寻找点的父节点
            if pop_node.left is not None: #添加tmp 元素
                tmp.append(pop_node.left)
            if pop_node.right is not None:
                tmp.append(pop_node.right)
        return None
    def delete(self, item):
        if self.root is None:  # 如果根为空,就什么也不做
            return False

        parent = self.get_parent(item)
        if parent:
            del_node = parent.left if parent.left.item == item else parent.right  # 待删除节点
            if del_node.left is None:
                if parent.left.item == item:
                    parent.left = del_node.right
                else:
                    parent.right = del_node.right
                del del_node
                return True
            elif del_node.right is None:
                if parent.left.item == item:
                    parent.left = del_node.left
                else:
                    parent.right = del_node.left
                del del_node
                return True
            else:  # 左右子树都不为空
                tmp_pre = del_node
                tmp_next = del_node.right
                if tmp_next.left is None:
                    # 替代
                    tmp_pre.right = tmp_next.right
                    tmp_next.left = del_node.left
                    tmp_next.right = del_node.right

                else:
                    while tmp_next.left:  # 让tmp指向右子树的最后一个叶子
                        tmp_pre = tmp_next
                        tmp_next = tmp_next.left
                    # 替代
                    tmp_pre.left = tmp_next.right
                    tmp_next.left = del_node.left
                    tmp_next.right = del_node.right
                if parent.left.item == item:
                    parent.left = tmp_next
                else:
                    parent.right = tmp_next
                del del_node
                return True
        else:
            return False

字典树

class TrieNode:
    def __init__(self):
        self.nodes = dict()  # 构建字典
        self.is_leaf = False
    def insert(self, word: str):  
        curr = self
        for char in word:
            if char not in curr.nodes:
                curr.nodes[char] = TrieNode()
            curr = curr.nodes[char]
        curr.is_leaf = True
    def insert_many(self, words: [str]):
        for word in words:
            self.insert(word)
    def search(self, word: str):
        curr = self
        for char in word:
            if char not in curr.nodes:
                return False
            curr = curr.nodes[char]
        return curr.is_leaf

class heap(object):
    def __init__(self):
        #初始化一个空堆,使用数组来在存放堆元素,节省存储
        self.data_list = []
    def get_parent_index(self,index):
        #返回父节点的下标
        if index == 0 or index > len(self.data_list) -1:
            return None
        else:
            return (index -1) >> 1
    def swap(self,index_a,index_b):
        #交换数组中的两个元素
        #Python学习交流QQ群:857662006 
        self.data_list[index_a],self.data_list[index_b] = self.data_list[index_b],self.data_list[index_a]
    def insert(self,data):
        #先把元素放在最后,然后从后往前依次堆化
        #这里以大顶堆为例,如果插入元素比父节点大,则交换,直到最后
        self.data_list.append(data)
        index = len(self.data_list) -1 
        parent = self.get_parent_index(index)
        #循环,直到该元素成为堆顶,或小于父节点(对于大顶堆) 
        while parent is not None and self.data_list[parent] < self.data_list[index]:
            #交换操作
            self.swap(parent,index)
            index = parent
            parent = self.get_parent_index(parent)
    def removeMax(self):
        #删除堆顶元素,然后将最后一个元素放在堆顶,再从上往下依次堆化
        remove_data = self.data_list[0]
        self.data_list[0] = self.data_list[-1]
        del self.data_list[-1]

        #堆化
        self.heapify(0)
        return remove_data
    def heapify(self,index):
        #从上往下堆化,从index 开始堆化操作 (大顶堆)
        total_index = len(self.data_list) -1
        while True:
            maxvalue_index = index
            if 2*index +1 <=  total_index and self.data_list[2*index +1] > self.data_list[maxvalue_index]:
                maxvalue_index = 2*index +1
            if 2*index +2 <=  total_index and self.data_list[2*index +2] > self.data_list[maxvalue_index]:
                maxvalue_index = 2*index +2
            if maxvalue_index == index:
                break
            self.swap(index,maxvalue_index)
            index = maxvalue_index
相关文章
|
11天前
|
数据挖掘 PyTorch TensorFlow
|
21天前
|
机器学习/深度学习 算法 数据挖掘
6种有效的时间序列数据特征工程技术(使用Python)
在本文中,我们将探讨使用日期时间列提取有用信息的各种特征工程技术。
76 0
|
5天前
|
机器学习/深度学习 数据采集 算法
数据稀缺条件下的时间序列微分:符号回归(Symbolic Regression)方法介绍与Python示例
有多种方法可以处理时间序列数据中的噪声。本文将介绍一种在我们的研究项目中表现良好的方法,特别适用于时间序列概况中数据点较少的情况。
20 1
数据稀缺条件下的时间序列微分:符号回归(Symbolic Regression)方法介绍与Python示例
|
8天前
|
算法 Python
揭秘!Python数据魔术师如何玩转线性回归,让你的预测精准到不可思议
【9月更文挑战第13天】在数据科学领域,线性回归以其优雅而强大的特性,将复杂的数据关系转化为精准的预测模型。本文将揭秘Python数据魔术师如何利用这一统计方法,实现令人惊叹的预测精度。线性回归假设自变量与因变量间存在线性关系,通过拟合直线或超平面进行预测。Python的scikit-learn库提供了简便的LinearRegression类,使模型构建、训练和预测变得简单直接。
22 5
|
10天前
|
存储 算法 测试技术
预见未来?Python线性回归算法:数据中的秘密预言家
【9月更文挑战第11天】在数据的海洋中,线性回归算法犹如智慧的预言家,助我们揭示未知。本案例通过收集房屋面积、距市中心距离等数据,利用Python的pandas和scikit-learn库构建房价预测模型。经过训练与测试,模型展现出较好的预测能力,均方根误差(RMSE)低,帮助房地产投资者做出更明智决策。尽管现实关系复杂多变,线性回归仍提供了有效工具,引领我们在数据世界中自信前行。
28 5
|
10天前
|
机器学习/深度学习 数据挖掘 TensorFlow
🔍揭秘Python数据分析奥秘,TensorFlow助力解锁数据背后的亿万商机
【9月更文挑战第11天】在信息爆炸的时代,数据如沉睡的宝藏,等待发掘。Python以简洁的语法和丰富的库生态成为数据分析的首选,而TensorFlow则为深度学习赋能,助你洞察数据核心,解锁商机。通过Pandas库,我们可以轻松处理结构化数据,进行统计分析和可视化;TensorFlow则能构建复杂的神经网络模型,捕捉非线性关系,提升预测准确性。两者的结合,让你在商业竞争中脱颖而出,把握市场脉搏,释放数据的无限价值。以下是使用Pandas进行简单数据分析的示例:
25 5
|
10天前
|
存储 安全 算法
RSA在手,安全我有!Python加密解密技术,让你的数据密码坚不可摧
【9月更文挑战第11天】在数字化时代,信息安全至关重要。传统的加密方法已难以应对日益复杂的网络攻击。RSA加密算法凭借其强大的安全性和广泛的应用场景,成为保护敏感数据的首选。本文介绍RSA的基本原理及在Python中的实现方法,并探讨其优势与挑战。通过使用PyCryptodome库,我们展示了RSA加密解密的完整流程,帮助读者理解如何利用RSA为数据提供安全保障。
27 5
|
11天前
|
数据采集 数据挖掘 数据处理
使用Python和Pandas处理CSV数据
使用Python和Pandas处理CSV数据
43 5
|
12天前
|
数据采集 存储 数据挖掘
使用Python读取Excel数据
本文介绍了如何使用Python的`pandas`库读取和操作Excel文件。首先,需要安装`pandas`和`openpyxl`库。接着,通过`read_excel`函数读取Excel数据,并展示了读取特定工作表、查看数据以及计算平均值等操作。此外,还介绍了选择特定列、筛选数据和数据清洗等常用操作。`pandas`是一个强大且易用的工具,适用于日常数据处理工作。
|
13天前
|
安全 数据安全/隐私保护 Python
情书也能加密?Python AES&RSA,让每一份数据都充满爱的密码
【9月更文挑战第8天】在这个数字化时代,情书不再局限于纸笔,也可能以电子形式在网络中传递。为了确保其安全,Python提供了AES和RSA等加密工具,为情书编织爱的密码。首先,通过安装pycryptodome库,我们可以利用AES对称加密算法高效保护数据;接着,使用RSA非对称加密算法加密AES密钥和IV,进一步增强安全性。即使情书被截获,没有正确密钥也无法解读内容。让我们用Python为爱情编织一张安全的网,守护每份珍贵情感。
27 2