双链表 Python 实现

链表是其余链式结构的基础,一般来说链表搞懂了后面的栈和队列(只是链表加了些限定规则)也就懂了。再往后的二叉搜索树除了删除结点比较复杂之外其实其他操作(增改查)和链表的增改查都差不多。

早先用 C 写过很多次链表,用 Java 也写过几次,转到 Python 就没思路了。其实套路都一样。

// 结点,存数据域和前后指针
typedef struct _NODE{
	int item;
	struct _NODE *next;
	struct _NODE *prev;
}NODE, *PNODE;

// 链表,存头尾结点和其他信息
typedef struct _LIST{
	PNODE head;
	PNODE tail;
	int size;
}LIST, *PLIST;

上面是 C 中定义链表的写法,结构体的命名参考了 WIN32 的写法。
可以看到我们分别定义了两个结构体用来存储结点信息和链表信息,换到 OOP 就是将这两个结构体定义为一个两个类。

下面上 Python 代码:

'''
双链表部分 Python 实现
2020年5月28日13:47:22

C 里面的链表都已经刻在 DNA 里了,用 Python 还没有思路,其实套路都一样
定义一个节点域和链表即可'''

class Node(object):
    def __init__(self, value=None, next=None, prev=None):
        '''结点和数据域'''
        self.value = value
        self.next = next
        self.prev = prev

    def get_value(self):
        return self.value

    def get_next(self):
        return self.next

    def __str__(self):
        return f'NodeValue {self.value}'


class LinkedList(object):
    def __init__(self, value=None):
        '''链表类'''
        self.tail = self.head = Node(value)
        self.length = 1

    def append(self, value):
        node = Node(value, prev=self.tail)
        self.tail.next = node
        self.tail = node

    def pre_append(self, value):
        node = Node(value, self.head)
        self.head.prev = node
        self.head = node

    def get_length(self):
        return self.length

    def traverse(self, func):
        '''使用指定函数遍历链表'''
        head = self.head

        while head:
            func(head)
            head = head.next

    def re_traverse(self, func):
        '''反向遍历链表'''
        tail = self.tail

        while tail:
            func(tail)
            tail = tail.prev

    def reverse(self):
        '''反转链表还是不熟,双链表的反转其实和单链表反转同理'''
        prev, curr, next = None, self.head, self.head

        while next:
            next = next.next

            curr.prev = curr.next
            curr.next = prev

            prev = curr
            curr = next

        self.tail = self.head
        self.head = prev


def prt_value(node):
    print(node.value)


def main():
    li = LinkedList(-1)
    for i in range(10):
        li.append(i)

    li.reverse()
    li.append(100)
    li.pre_append(1010)
    li.traverse(prt_value)
    print('*' * 10)
    li.re_traverse(prt_value)
    # li.traverse(prt_value)

if __name__ == '__main__':
    main()

这段代码只实现了头插法和尾插法新增元素,删改查这三个操作都基于查,熟悉链表的话很容易实现。
另外 Python 不用考虑内存泄漏的问题,所以可以更加专注于实现。

唯一值得参考的是reverse这个方法,该方法实现了反转双链表的算法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值