数据结构与算法(python实现)

文章目录

  • 列表List
    • 数组array
    • 实现定长数组
  • 链表
    • 单链表
    • 双链表
  • 栈和队列
    • 队列

列表List

init[]
该操作会初始化一个Pylist对象,时间复杂度为 O ( 1 ) O(1) O(1)
append(1)
该操作会新分配4个Pylist对象来去存储,它的容量(最多能存储多少数据)是4,但长度(实际有多少数据)小于等于4,不会一次只分配一个。当存储新数据时,如果空间足够则时间复杂度 O ( 1 ) O(1) O(1)
当已经分配的空间不够用时,这时执行一个resize,重新分配空间(容量更大),时间复杂度退化为 O ( n ) O(n) O(n)
总的平均时间复杂度为 O ( 1 ) O(1) O(1)
insert
往中间插入,这需要重新开辟空间,时间复杂度为 O ( n ) O(n) O(n)
pop
默认最后一位,时间复杂度为 O ( 1 ) O(1) O(1),如果pop中间的数据,时间复杂度为 O ( n ) O(n) O(n)
remove
时间复杂度为 O ( n ) O(n) O(n)

所以如果需要频繁的执行insert, remove 和在中间pop的操作,list可能不合适。

数组array

使用列表居多,使用array,建议使用numpy.ndarray

实现定长数组

class Array():
    def __init__(self, size=32):
        self._size = size
        self._items = [None] * size

    def __getitem__(self, index):
        return self._items[index]

    def __setitem__(self, index, value):
        self._items[index] = value

    def __len__(self):
        return len(self._items)

    def clear(self, value=None):
        for i in range(len(self._items)):
            self._items[i] = value

    def __iter__(self):
        for item in self._items:
            yield item

链表

单链表

class Node:
    # 定义一个节点
    def __init__(self, data=None, next_node=None):
        self.data = data
        self.next = next_node

class LinkedList:
    def __init__(self, maxsize=None):
        self.head = Node()  # 头节点是虚节点,不存储数据
        self.maxsize = maxsize
        self.length = 0
        self.tail = None

    def __len__(self):
        return self.length

    def is_empty(self):
        return not self.head.next

    def append(self, data):
        # 创建新节点
        new_node = Node(data=data)

        # 在尾部插入新节点
        if self.tail is None:
            self.head.next = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node

        self.length += 1

    def appendleft(self, data):
        # 在头部插入新节点
        headnode = self.head.next
        new_node = Node(data=data)
        self.head.next = new_node
        new_node.next = headnode

        self.length += 1

    # 遍历整个链表
    def iter_node(self):
        curNode = self.head.next
        while curNode:
            yield curNode
            curNode = curNode.next

    def __iter__(self):
        for node in self.iter_node():
            yield node.data

    def print_lit(self):
        print('linked_list:')
        temp = self.head
        while temp is not None:
            print(temp.data)
            temp = temp.next

    # 翻转链表
    def reverse(self):
        prev = None
        current = self.head.next
        self.tail = current
        while current:
            next_node = current.next
            current.next = prev
            prev = current
            current = next_node
        self.head.next = prev

    def initlist(self,data_list):
        """
        将列表转换为链表
        """
        # 创建头结点
        self.head = Node(data_list[0])
        temp = self.head
        # 逐个为 data 内的数据创建结点, 建立链表
        for i in data_list[1:]:
            node = Node(i)
            temp.next = node
            temp = temp.next

    def insert(self, position: int, new_element: Node):
        if position < 0 or position > self.length:
            raise IndexError('position out index')
        
        temp = self.head
        if position == 0:
            new_element.next = temp
            self.head = new_element

        i = 0
        while i < position:
            pre = temp
            temp = temp.next 
            i += 1

        pre.next = new_element
        new_element.next = temp

    def remove(self, position: int):
        if position < 0 or position > self.length:
            raise IndexError('position out index')

        i = 0
        temp = self.head
        while temp != None:
            if position == 0:
                self.head = temp.next
                temp.next = None
                return

            pre = temp
            temp = temp.next
            i += 1

            if i == position:
                pre.next = temp.next
                temp.next = None
                return

    def swapNodes(self, d1, d2):
        prevD1 = None
        prevD2 = None
        if d1 == d2:
            return
        else:
            D1 = self.head
            while D1 is not None and D1.data != d1:
                prevD1 = D1
                D1 = D1.next
            D2 = self.head
            while D2 is not None and D2.data != d2:
                prevD2 = D2
                D2 = D2.next
            if D1 is None and D2 is None:
                return
            if prevD1 is not None:
                prevD1.next = D2
            else:
                self.head = D2
            if prevD2 is not None:
                prevD2.next = D1
            else:
                self.head = D1
            temp = D1.next
            D1.next = D2.next
            D2.next = temp



if __name__ == '__main__':
    list = LinkedList()         

双链表

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():
            # 如果是空链表,将 node 赋值给 _head
            self._head = node
        else:
            # 将 node 的 next 属性指向头节点 _head
            node.next = self._head
            # 将头节点 _head 的 prev 属性指向 node
            self._head.prev = node
            # 将 node 赋值给 _head
            self._head = node

    def append(self, item):
        # 尾部插入元素
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将 node 赋值给 _head
            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.get_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 Stack:
    def __init__(self, limit=10):
        self.stack = []
        self.limit = limit

    def push(self, data):
        if len(self.stack) >= self.limit:
            raise IndexError('超出容量极限')
        
        self.stack.append(data)

    def pop(self):
        if self.stack:
            return self.stack.pop()
        else:
            raise IndexError('pop from a empty stack')

    def peek(self):
        if self.stack:
            return self.stack[-1]
        else:
            raise IndexError('peek from a empty stack') 

    def isempty(self):
        return not bool(self.stack)

    def size(self):
        return len(self.stack)

def balanced_parentheses(parentheses):
    stack = Stack(len(parentheses))
    # print(type(stack.limit))
    # print(stack.limit)

    for parenthesis in parentheses:
        if parenthesis == '(':
            stack.push(parenthesis)
        elif parenthesis == ')':
            if stack.isempty():
                return False
            stack.pop()

    return stack.isempty()

if __name__ == "__main__":
    examples = ['((()))', '((())', '(()))']
    print('Balanced parentheses demonstraction:\n')
    for example in examples:
        print(example + ':' + str(balanced_parentheses(example)))

队列

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():
            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)

你可能感兴趣的:(python)