链表的python实现

python不像C语言,没有指针类型,那么如何实现链表之类的数据结构呢。我们可以利用python变量创建的特点,来进行实现。

python创建一个变量名,实际上是给一个值添加了一个标识符,所以会出现以下情况:

a = [1,2,3]
b = a
b.append(4)
print(a)
print(b)

得到的输出是

>>>a
[1,2,3,4]
>>>b
[1,2,3,4]

这是因为,a和b都是对列表的引用,尽管我们使用了a=b来进行赋值,但是只是为那个列标添加了一个标识符,所以当a的值改变后,b的值也会改变。这种行为有点“像”C语言中的指针。

但是并不是每一种类型都是如此,python为一些“热门”的整数预留了地址,所以会出现以下情况

a = 1
b = a
a = 2
print(a,b)

得到的结果却是

>>>a
2
>>>b
1

python为1和2这两个数字留好了特定的内存地址,所以给a重新赋值2的时候,相当于把a这个标签“贴到”了数字2的地址上,而b这个标签仍然“贴在”数字1的地址上,所以不会出现和上面列表一样的情况。感兴趣的读者可以编写一段代码,找出python为哪些数字预留了特定的地址。

有了上面的基础,我们可以使用python来实现一个单链表

class Node:
    def __init__(self,data=None):
        self.data = data
        self.next = None

这里定义了一个节点类,节点有两个属性,分别是值和下一个节点的地址,这里默认值为None

class LinkList(Node):
    def __init__(self,*args):
        super().__init__(0)
        for i in args[::-1]:
            self.headInsert(i)
            self.data += 1

    def headInsert(self,value):
        node = Node(value)
        node.next = self.next
        self.next = node

    def output(self,end="\r"):
        tem = self.next
        first = True
        while tem!=None:
            if first:
                print(tem.data,end="")
                first = False
            else:
                print("->",tem.data,end="")
            tem = tem.next
        print(end)
    def endInsert(self,value):
        tem = self
        while tem.next!=None:
            tem = tem.next
        node = Node(value)
        node.next = None
        tem.next = node

    def insert(self,pos,value)->bool:
        if pos<0|pos>self.data-1:
            return False
        tem = self
        for i in range(pos):
            tem = tem.next
        node = Node(value)
        node.next = tem.next
        tem.next = node
        self.data += 1
        return True

这里定义了一个链表类型,我们实现了一些基本方法,包括头插,尾插,插入,遍历输出,下面来测试一下代码

l = LinkList(1,2,3)
l.output()

输出结果如下

1-> 2-> 3

这就是单链表的创建,如果想创建循环单链表,则只需要将节点的默认值设置为self,然后在尾插法的部分把尾节点的next属性赋值为self,然后修改尾插和遍历输出的循环结束条件为:tem!=self即可

下面我们来创建一个双链表

class Node:
    def __init__(self,value=None):
        self.data = value
        self.next = None
        self.pre = None

节点的类型略有变化,添加了一个前驱的属性

class DoubleLinkList(Node):
    def __init__(self,*args):
        super().__init__(0)
        for i in args[::-1]:
            self.headInsert(i)
            self.data+=1

    def headInsert(self,value):
        node = Node(value)
        node.next = self.next
        node.pre = self
        if self.next != None:
            self.next.pre = node
        self.next = node
    def output(self,end="\r"):
        tem = self.next
        first = True
        while tem!=None:
            if first:
                print(tem.data,end="")
                first = False
            else:
                print("->",tem.data,end="")
            tem = tem.next
        print(end)

然后是双链表类,同样实现了头插法来辅助创建,双链表的插入操作和尾插操作于单链表相似,不再写出。来测试一下双链表的代码

dl = DoubleLinkList(1,4,2,3)
dl.output()
print(dl.next.next.next.next.pre.data)
print(dl.data)

结果如下

1-> 4-> 2-> 3
2
4

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值