数据结构Python实现之链表

链表结构是最常用的数据结构,和数组一样,链表结构是一个具体的数据类型,它实现了很多类型的集合,包括列表。链表结构的两种最简单的结构是单链表结构和双链表结构。
图1显示了两种类型的链表结构。

这里写图片描述

1.单链表的Python实现

首先定义一个单链表节点类`

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

接着定义一个单链表结构类

class LinkedList(object):
    def __init__(self):#初始化链表的头节点以及链表的长度
        self.head = Node()
        self.length = 0
    def __len__(self):#返回链表的长度
        return self.length

1.在链表末尾插入节点

def append(self,value):#添加节点,从末尾处添加
        node = Node(value)
        if self.length==0:
            self.head.next=node
            self.length += 1
        else:
            curnode = self.head.next
            while curnode.next!=None:
                curnode = curnode.next
            curnode.next=node
            self.length += 1
测试:
l=LinkedList()
l.append(3)
l.append(5)
l.append(9)
print('链表长度:',len(l))
i=1
for node in l:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
链表长度: 31个链表节点的值:32个链表节点的值:53个链表节点的值:9

2.在链表开始出插入节点

def start_insert(self,insert_value):#在开始出插入
        node = Node(insert_value)
        if self.length==0:
            self.head.next = node
        else:
            tmp_node=self.head.next
            self.head.next = node
            node.next = tmp_node
        self.length +=1
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
print('链表长度:',len(l))
i=1
for node in l:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
链表长度: 41个链表节点的值:102个链表节点的值:93个链表节点的值:54个链表节点的值:3

3.在链表任意位置插入节点

def insert(self,location,value):#在任意位置插入节点
        node = Node(value)
        if self.length==0:
            self.head.next = node
            self.length += 1#插入一个节点,链表长度加1
        else:
            for nd in self.iter_node():
                if nd.value == location:
                    tmp_node = nd.next
                    nd.next = node
                    node.next = tmp_node
                    self.length += 1
                    return True
            return False#返回False,未找到插入位置
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
print('插入之前链表长度:',len(l))
i=1
print('遍历链表:')
for node in l:
    print('         第%d个链表节点的值:%d'%(i,node))
    i += 1
l.insert(3,100)#在末尾插入
l.insert(10,200)#在开始处插入
l.insert(5,300)#在任意位置插入节点
l.insert(200,2000)#在node.value==200处插入一个node.value=2000的节点
print('插入之后链表长度:',len(l))
print('遍历链表:')
i=1
for node in l:
    print('         第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
插入之前链表长度: 4
遍历链表:
         第1个链表节点的值:102个链表节点的值:93个链表节点的值:54个链表节点的值:3
插入之后链表长度: 8
遍历链表:
         第1个链表节点的值:102个链表节点的值:2003个链表节点的值:20004个链表节点的值:95个链表节点的值:56个链表节点的值:3007个链表节点的值:38个链表节点的值:100

4.遍历链表

def __iter__(self):#遍历链表节点
    for node in self.iter_node():
        yield node.value
def iter_node(self):
    curnode = self.head.next
    while curnode.next !=None:
        yield curnode
        curnode = curnode.next
    if curnode.next == None:
        yield curnode
5.搜索节点,按照value搜索
def search(self,value):#搜索节点
    index = 1
    if self.length==0:#如果长度为0,则表示链表结构中只有一个头节点
        return -1#返回-1,表示不存在该节点
    else:
        for node in self.iter_node():
            if node.value == value:
                return index #搜索到节点的序号
            index += 1
        return -1#未搜索到节点
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
print('遍历链表:')
i=1
for node in l:
    print('         第%d个链表节点的值:%d'%(i,node))
    i += 1
print('value_3 index:',l.search(3))#输出搜索到的节点的序号
print('value_5 index:',l.search(5))
print('value_10 index:',l.search(10))
print('value_100 index:',l.search(100))#若未搜索到目标性,则返回-1
输出:
遍历链表:
         第1个链表节点的值:102个链表节点的值:93个链表节点的值:54个链表节点的值:3
value_3 index: 4
value_5 index: 3
value_10 index: 1
value_100 index: -1

6.替换节点,按照value替换

def replace(self,old_value,new_value):#替换操作
    index = 0
    if self.length==0:
        return False#如果长度等于0,返回False
    else:
        for node in self.iter_node():
            if node.value == old_value:
                node.value=new_value
                index += 1
    if index!=0:
        return index#替换节点数
    else:
        return False #替换的目标项不存在
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
l.start_insert(10)
l.start_insert(5)
l.start_insert(5)
print('遍历链表:')
i=1
for node in l:
    print('         第%d个链表节点的值:%d'%(i,node))
    i += 1
print('替换的节点数量:',l.replace(3,300))#把节点的值3替换成300,按照值替换,并非按照序号替换
print('替换的节点数量:',l.replace(5,500))#替换成功,返回替换的节点数量
print('替换的节点数量:',l.replace(9,900))
print('替换的节点数量:',l.replace(10,1000))
print('遍历链表:')
i=1
for node in l:
    print('         第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
遍历链表:
         第1个链表节点的值:52个链表节点的值:53个链表节点的值:104个链表节点的值:105个链表节点的值:96个链表节点的值:57个链表节点的值:3
替换的节点数量: 1
替换的节点数量: 3
替换的节点数量: 1
替换的节点数量: 2
遍历链表:
         第1个链表节点的值:5002个链表节点的值:5003个链表节点的值:10004个链表节点的值:10005个链表节点的值:9006个链表节点的值:5007个链表节点的值:300

7.删除节点,在任意位置删除

def del_node(self,del_value):#删除节点
    Flag = False
    if self.length==0:
        return Flag
    else:
        previous_node = self.head
        for curnode in self.iter_node():
            if curnode.value == del_value:
                previous_node.next=curnode.next
                del curnode
                self.length -= 1
                Flag = True
            else:
                previous_node = curnode
        return Flag
def output(l):
    print('遍历链表:')
    i=1
    for node in l:
        print('         第%d个链表节点的值:%d'%(i,node))
        i += 1
测试:
l=LinkedList()
l.append(3)
l.append(5)
l.append(9)
l.append(10)
l.append(10)
l.append(5)
l.append(5)
l.append(11)
output(l)
print('删除节点值为3的节点:',l.del_node(3))#返回True,表示删除成功,否则返回False
output(l)
print('删除节点值为5的节点:',l.del_node(5))
output(l)
print('删除节点值为9的节点:',l.del_node(9))
output(l)
print('删除节点值为11的节点:',l.del_node(11))
output(l)
输出:
遍历链表:
         第1个链表节点的值:32个链表节点的值:53个链表节点的值:94个链表节点的值:105个链表节点的值:106个链表节点的值:57个链表节点的值:58个链表节点的值:11
删除节点值为3的节点: True
遍历链表:
         第1个链表节点的值:52个链表节点的值:93个链表节点的值:104个链表节点的值:105个链表节点的值:56个链表节点的值:57个链表节点的值:11
删除节点值为5的节点: True
遍历链表:
         第1个链表节点的值:92个链表节点的值:103个链表节点的值:104个链表节点的值:11
删除节点值为9的节点: True
遍历链表:
         第1个链表节点的值:102个链表节点的值:103个链表节点的值:11
删除节点值为11的节点: True
遍历链表:
         第1个链表节点的值:102个链表节点的值:10

2.双链表的Python实现

1.添加节点,从末尾添加

class Node(object):
    def __init__(self,value=None,prev=None,next=None):
        self.value = value
        self.prev = prev
        self.next = next

class Double_LinkedList(object):
    def __init__(self):#初始化双链表只有一个头结点,它的前向指针和后向指针都指向自己,长度为0
        node = Node()
        node.prev = node
        node.next = node
        self.head = node
        self.length = 0
    def __len__(self):
        return self.length
    def headnode(self):#获取第一个节点
        return self.head.next
    def tailnode(self):#获取最后一个节点
        return self.head.prev
    def append(self,value):#添加节点,从末尾添加
        node = Node(value)
        tail_node = self.tailnode()
        tail_node.next = node
        node.prev = tail_node
        node.next = self.head
        self.head.prev = node
        self.length += 1
测试:
DL = Double_LinkedList()
DL.append(1)
DL.append(2)
DL.append(3)
DL.append(3)
DL.append(2)
DL.append(1)
print('双链表的长度为:',DL.length)
i=1
for node in DL:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
双链表的长度为: 61个链表节点的值:12个链表节点的值:23个链表节点的值:34个链表节点的值:35个链表节点的值:26个链表节点的值:1

2.在开头添加节点

def head_append(self,value):
        node =Node(value)
        if self.head.next is self.head:
            node.next = self.head
            node.prev = self.head
            self.head.next = node
            self.head.prev = node
        else:
            node.prev = self.head
            head_node = self.headnode()
            self.head.next = node
            head_node.prev = node
            node.next = head_node
        self.length += 1
测试:
DL = Double_LinkedList()
DL.head_append(1)
DL.head_append(2)
DL.head_append(3)
DL.head_append(6)
DL.head_append(7)
print('双链表的长度为:',DL.length)
i=1
for node in DL:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
双链表的长度为: 51个链表节点的值:72个链表节点的值:63个链表节点的值:34个链表节点的值:25个链表节点的值:1

3.在任意位置添加节点

def insert(self,index,value):#在任意位置插入新节点
        node = Node(value)
        i = 1
        if self.length<index:
            raise Exception('out of range')
        if self.head.next is self.head:
            self.head.next = node
            self.head.prev = node
            node.next = self.head
            node.prev = self.head
            self.length += 1
            return True
        else:
            if index==0:
                self.head_append(value)
                return True
            for cur_node in self.iter_node():
                if i == index:
                    next_node = cur_node.next
                    node.prev = cur_node
                    node.next = next_node
                    cur_node.next = node
                    next_node.prev = node
                    self.length += 1
                    return True
                i += 1
测试:
DL = Double_LinkedList()
DL.insert(0,2)#在位置0处插入一个节点值为2的新节点
DL.insert(1,3)#在位置1处插入一个节点值为3的新节点
DL.insert(2,4)#在位置2处插入一个节点值为4的新节点
DL.insert(0,11)#在位置0处插入一个节点值为11的新节点
DL.insert(2,22)#在位置2处插入一个节点值为22的新节点
DL.insert(5,55)#在位置5处插入一个节点值为55的新节点
print('双链表的长度为:',DL.length)
i=1
for node in DL:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
双链表的长度为: 61个链表节点的值:112个链表节点的值:23个链表节点的值:224个链表节点的值:35个链表节点的值:46个链表节点的值:55

4.删除节点

def del_node(self,index):#删除节点
        i=1
        for cur_node in self.iter_node():
            if i == index:
                next_node=cur_node.next
                prev_node=cur_node.prev
                prev_node.next = next_node
                next_node.prev = prev_node

                self.length -= 1
                return True
            i += 1

测试:
DL = Double_LinkedList()
DL.insert(0,2)#在位置0处插入一个节点值为2的新节点
DL.insert(1,3)#在位置1处插入一个节点值为3的新节点
DL.insert(2,4)#在位置2处插入一个节点值为4的新节点
DL.insert(1,8)#在位置2处插入一个节点值为4的新节点
print('双链表的长度为:',DL.length)
i=1
for node in DL:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
print('开始删除。。。。。。')
DL.del_node(1)
DL.del_node(3)
print('双链表的长度为:',DL.length)
i=1
for node in DL:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
输出:
双链表的长度为: 41个链表节点的值:22个链表节点的值:83个链表节点的值:34个链表节点的值:4
开始删除。。。。。。
双链表的长度为: 21个链表节点的值:82个链表节点的值:3

5.遍历输出节点

def iter_node(self):#遍历节点
    if self.head.next is self.head:
        return -1
    cur_node = self.head.next
    while cur_node.next is not self.head:
        yield cur_node
        cur_node = cur_node.next
    yield cur_node
def __iter__(self):#遍历节点,输出每个节点的值
     for node in self.iter_node():
         yield node.value
def reverse_iter_node(self):#反向遍历节点
    if self.head.prev is self.head:
        return False
    cur_node = self.head.prev
    while cur_node.prev is not self.head:
        yield cur_node
        cur_node = cur_node.prev
    yield cur_node
测试:
DL = Double_LinkedList()
DL.insert(0,2)#在位置0处插入一个节点值为2的新节点
DL.insert(1,3)#在位置1处插入一个节点值为3的新节点
DL.insert(2,4)#在位置2处插入一个节点值为4的新节点
DL.insert(1,8)#在位置2处插入一个节点值为4的新节点
print('双链表的长度为:',DL.length)
i=1
print('正向遍历节点:')
for node in DL:
    print('第%d个链表节点的值:%d'%(i,node))
    i += 1
print('反向遍历节点:')
print([node.value for node in DL.reverse_iter_node()])
输出:
双链表的长度为: 4
正向遍历节点:
第1个链表节点的值:22个链表节点的值:83个链表节点的值:34个链表节点的值:4
反向遍历节点:
[4, 3, 8, 2]

猜你喜欢

转载自blog.csdn.net/qq_16000815/article/details/81271859