Python学习-------数据结构应用(链表)

链表,顾名思义,是用链子串起来的列表(好吧,这知识把这两个字拆开了)。重点在于“链”字,链表中每一个元素被称为结点,每一个节点包括两个域:数据域和地址域。数据域用来存放本身的数据,地址域用来存放下一个结点或上一个节点的内存地址。操作链表的时候通过当前结点的地址域寻找下一个结点。只能顺序遍历,不能像列表一样可以随机遍历。

一。单向链表---每一个node存储的内存地址不连续,由前一个node的指针找到下一个node的内存地址。

# 单向链表:每一个node存储的内存地址不连续,由前一个node的指针找到下一个node的内存地址。
class Node:
    """创建节点"""
    def __init__(self, data=None):
        """ 初始化

            添加节点本身数据
            添加指向下一个节点的地址
        """
        self.data = data
        self.next = None

    def get_data(self):
        """返回结点本身的数据"""
        return self.data

    def get_next(self):
        """得到下一个结点的地址"""
        return self.next

    def set_data(self, new_data):
        """修改结点本身的数据"""
        self.data = new_data

    def set_next(self, new_next):
        """修改指向下一个结点的地址"""
        self.next = new_next


class UnorderList:
    """ 无序链表:

        本例采用的是单向链表,链表中每一个节点由两部分组成,分别是节点本身数据域和指向下一个节点地址域。

        单向链表的方法包括添加、删除、搜索、判断是否为空、遍历等
        
        在无序链表中,新结点对于列表中已存在的其他结点的特定位置不重要。新结点可以保存在任何地方。
    """
    def __init__(self):
        """初始化"""
        self.head = None  # 头结点

    def is_empty(self):
        """判断链表是否为空"""
        return True if self.head == None else False

    def add(self, data):
        """添加新节点"""
        temp = Node(data)  # 创建新结点
        temp.set_next(self.head)  # 将新结点链接之前的list
        self.head = temp   # 将新结点设为head

    def search(self, data):
        """查询链表里是否存在data这个结点数据"""
        current = self.head
        found = False
        while current and not found:
            if current.get_data() == data:
                found = True
            else:
                current = current.get_next()
        return found

    def delete(self, data):
        """删除链表中数据为data的结点"""
        current = self.head
        previous = None
        found = False
        while current and not found:
            if current.get_data() == data:
                found = True
            else:
                previous = current
                current = current.get_next()
        if not current:
            print(f"没有找到数据{data}")
            return False
        elif not previous:
            self.head = current.get_next()
        else:
            previous.set_next(current.get_next())

    def show(self):
        """输出链表的各个节点数据,返回链表长度"""
        current = self.head
        count = 0
        while current:
            print(current.data)
            count += 1
            current = current.next
        return count


class OrderList:
    """有序链表:

        与无序链表之间的区别在于添加新节点的时候,
        不再是盲目的添加在表头,而是与现有链表节点的数据进行比较,
        然后添加在合适的位置
    """
    def __init__(self):
        """初始化链表"""
        self.head = None

    def is_empty(self):
        """判断链表是否为空"""
        return True if self.head == None else False

    def add(self, data):
        """添加新节点,并将节点数据进行比较排序,本例是递升有序链表"""
        current = self.head
        previous = None
        stop = False
        while current and not stop:
            if type(current.get_data()) == type(data) and current.get_data() > data:
                stop = True
            else:
                previous = current
                current = current.get_next()
        temp = Node(data)
        if not previous:
            temp.set_next(self.head)
            self.head = temp
        else:
            temp.set_next(current)
            previous.set_next(temp)

    def search(self, data):
        """查询链表里是否存在data这个结点数据"""
        current = self.head
        found = False
        stop = False
        while current and not found and not stop:
            if type(current.get_data()) == type(data):
                if current.get_data() == data:
                    found = True
                elif current.get_data() > data:
                    stop = True
            current = current.next
        return found

    def delete(self, data):
        """删除链表中数据为data的结点"""
        current = self.head
        previous = None
        found = False
        while current and not found:
            if current.get_data() == data:
                found = True
            else:
                previous = current
                current = current.get_next()
        if not current:
            print(f"没有找到数据{data}")
            return False
        elif not previous:
            self.head = current.get_next()
        else:
            previous.set_next(current.get_next())

    def show(self):
        """输出链表的各个节点数据,返回链表长度"""
        current = self.head
        count = 0
        while current:
            print(current.data)
            count += 1
            current = current.next
        return count


def main():
    """测试"""
    link_unorder = UnorderList()
    link_unorder.add(3)
    link_unorder.show()
    link_unorder.add('aaa')
    link_unorder.show()
    print(link_unorder.is_empty())
    print(link_unorder.search(3))
    print(link_unorder.search('aaa'))
    link_unorder.delete(2)
    link_unorder.delete(3)
    print(link_unorder.show())
    print("以下是有序链表的测试")
    link_order = OrderList()
    link_order.add(3)
    link_order.show()
    link_order.add(6)
    link_order.show()
    link_order.add(1)
    link_order.show()
    link_order.add('aaa')
    link_order.add('daa')
    link_order.add('baa')
    link_order.show()
    print(link_order.is_empty())
    print(link_order.search(3))
    print(link_order.search('aaa'))
    link_order.delete(2)
    link_order.delete(3)
    link_order.delete('baa')
    print(link_order.show())

if __name__ == '__main__':
    main()

二、双向链表------每一个节点既指向前一个节点,又指向后一个节点


class DoubleNode:
    """创建节点"""
    def __init__(self, data=None):
        """初始化"""
        self.data = data
        self.next = None
        self.prev = None

    def get_data(self):
        """返回结点本身的数据"""
        return self.data

    def set_data(self, new_data):
        """修改结点本身的数据"""
        self.data = new_data

    def get_next(self):
        """得到下一个结点的地址"""
        return self.next

    def get_previous(self):
        """得到上一个结点的地址"""
        return self.prev

    def set_next(self, new_next):
        """修改指向下一个结点的地址"""
        self.next = new_next

    def set_previous(self, new_prev):
        """修改指向上一个结点的地址"""
        self.prev = new_prev


class DoubleLinkedList():
    """ 双向链表:

        与传统的单向链表区别在于,双向链表的每一个节点由三部分组成,分别是节点本身数据域,指向前一个节点地址域,指向后一个结点地址域。我们既可以从表头和表尾两个方向进行操作,每个方向可以看做是一个单向链表。
        
        双向链表与单向链表的方法大致相同。都包括添加、删除、搜索、判断是否为空、遍历等
    """
    def __init__(self):
        """ 初始化双向链表

            本例的初始化是初始化两个节点,一个头结点,一个尾结点,这两个节点可以充当哨兵的作用。这样做的好处是添加新节点的时候可以不用判断这个节点是否为第一个节点,删除节点的时候也可以变得简单。不好的地方是多余了两个节点的内存。
        """
        head = DoubleNode()
        tail = DoubleNode()
        self.head = head
        self.tail = tail
        self.head.next = self.tail
        self.tail.prev = self.head

    def search(self, data):
        """ 查找数据域为data的结点:

            若成功找到该节点,则返回第一个数据域为data的结点对象。
            若查找失败则返回None。
        """
        node = self.head.next
        while node != self.tail:
            if node.data == data:
                return node
            node = node.next
        return None

    def size(self):
        """获取链表的长度"""
        length = 0
        node = self.head.next
        while node != self.tail:
            length += 1
            node = node.next
        return length

    def add(self, data):
        """ 添加节点:

            因为初始化链表的时候就创建了头尾节点,所以新增节点统一看做中间节点插入便可。
        """
        node = DoubleNode(data)
        prev_node = self.tail.prev
        prev_node.next = node
        node.prev = prev_node
        self.tail.prev = node
        node.next = self.tail
        return 'OK'

    def delete(self, data):
        """ 删除数据域为data的结点"""
        node = self.search(data)
        if node:
            prev_node = node.prev
            next_node = node.next
            prev_node.next = next_node
            next_node.prev = prev_node
            return True
        else:
            return False

    def show(self):
        """ 遍历双向链表:

            可以正向遍历:以头结点为起始结点(本例)。
            也可以反向遍历:以尾结点为起始结点
        """
        node = self.head.next
        while node != self.tail:
            print(node.data)
            node = node.next

    def is_empty(self):
        return self.head.next == self.tail


def main():
    """测试"""
    double_link = DoubleLinkedList()
    print(double_link.is_empty())
    double_link.add('aaaa')
    double_link.add(4)
    double_link.show()
    print(double_link.search('aaaa'))
    print(double_link.search(3))
    print(double_link.size())
    print(double_link.delete('bbb'))
    print(double_link.delete(4))
    double_link.show()


if __name__ == '__main__':
    main()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值