VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 单链表-Python实现-jupyter->markdown 格式测试(2)

"""单链表""" def __init__(self, node=None): self.__head = node self.next = None def is_empty(self): """链表是否为空""" # 只要 __head指向的节点是None即链表为空 return self.__head == None def length(self): """链表的长度""" # 让指针(游标cur)有首先指向头节点对象 cur -> __head # 即 cur, __head 都指向了头节点对象 cur = self.__head # 开始计数, 让指针一边移动, 则一边计数 count = 0 # while 循环,让游标移动, 停止条件是当指针指向当前节点的next值为None时 # 关于count取值, 0:cur=None, 1:cur.next == None (指针指向哪为位置) while cur != None: count += 1 # 实现指针的"移动": Python中其实就是"="表示 "->" , 注意'='要从右往左看 cur = cur.next # 右到左: 将当前节点的next, 让cur去指向 return count def travel(self): """元素遍历""" # cur->__head cur = self.__head # 移动, 然后print节点的元素, 当cur==None时终止 while cur != None: print(cur.data, end=' ' ) cur = cur.next def append(self, item): """尾部添加元素""" node = Node(item) # 用户只关心值, 不关心指针 # 从头往后遍历 cur = self.__head # 考虑空链表情况 if cur is None: if self.is_empty(): # 直接将 __head -> node即可 self.__head = node else: while cur.next != None: cur = cur.next # 将尾节点的next -> node cur.next = node def add(self, item): """从头部插入元素""" node = Node(item) # 顺序很关键, 先node的next指向原先 __head所指向的节点, 然后再更新__head->node node.next = self.__head.next self.__head = node def insert(self, pos, item): """从任意位置插入元素""" # 考虑pos特殊情况 if pos <= 0: self.add(item) elif pos > (self.length()-1): # 不能包含 ==, 因为insert是前插入哦 self.append(item) else: node = Node(item) # 前一个节点, 引入一个游标 pre 表示前一个节点 pre = self.__head count = 0 while count < (pos-1): # 到该位置的前一个节点时终止 count += 1 pre = pre.next # 移动 # 当循环结束后,pre指向(pos-1) 对该位置的前一个节点操作: # 1. 先用node.next -> 原先节点指向的node # 2. pre的next -> node node.next = pre.next pre.next = node def search(self, item): """查找元素""" cur = self.__head # 循环遍历比较值即可 while cur != None: if cur.data == item: return True else: # 记得移动游标 ,不然就死循环了 cur = cur.next return False

remove实现

  • 删除某个元素, 删掉第一次找到的那个元素哦
  • 原理: cur找到该节点后, 用pre.next -> cur.next 即可
  • 即需要两个游标: pre 和cur

但其实, 只需要pre就能达到效果呢

  • pre.next -> node.next 即** pre.next -> pre.next.next**
class Node(object):
    """节点类"""
    def __init__(self, data=None):
        self.data = data
        self.next = None  

class SingleLinkList(object):
    """单链表"""
    def __init__(self, node=None):
        self.__head = node 
        self.next = None
    
    def is_empty(self):
        """链表是否为空"""
        # 只要 __head指向的节点是None即链表为空
        return self.__head == None
    
    def length(self):
        """链表的长度"""
        # 让指针(游标cur)有首先指向头节点对象 cur -> __head 
        # 即 cur, __head 都指向了头节点对象
        cur = self.__head
        # 开始计数, 让指针一边移动, 则一边计数
        count = 0 
        # while 循环,让游标移动, 停止条件是当指针指向当前节点的next值为None时
        # 关于count取值, 0:cur=None, 1:cur.next == None (指针指向哪为位置)
        while cur != None:
            count += 1 
            # 实现指针的"移动": Python中其实就是"="表示 "->" , 注意'='要从右往左看
            cur = cur.next  # 右到左: 将当前节点的next, 让cur去指向
        return count
            
        
    def travel(self):
        """元素遍历"""
        # cur->__head
        cur = self.__head
        # 移动, 然后print节点的元素, 当cur==None时终止
        while cur != None:
            print(cur.data, end=' ' )
            cur = cur.next
        
    def append(self, item):
        """尾部添加元素"""
        node = Node(item)  # 用户只关心值, 不关心指针
        # 从头往后遍历
        cur = self.__head
        # 考虑空链表情况 if cur is None:
        if self.is_empty():
            # 直接将 __head -> node即可
            self.__head = node
        else:
            while cur.next != None:
                cur = cur.next
            # 将尾节点的next -> node
            cur.next = node

    def add(self, item):
        """从头部插入元素"""
        node = Node(item)
        # 顺序很关键, 先node的next指向原先 __head所指向的节点, 然后再更新__head->node
        node.next = self.__head.next
        self.__head = node
        
    def insert(self, pos, item):
        """从任意位置插入元素"""
        # 考虑pos特殊情况
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):  # 不能包含 ==, 因为insert是前插入哦
            self.append(item)
        else:
            node = Node(item)
            # 前一个节点, 引入一个游标 pre 表示前一个节点
            pre = self.__head

            count = 0
            while count < (pos-1):  # 到该位置的前一个节点时终止
                count += 1
                pre = pre.next  # 移动
            # 当循环结束后,pre指向(pos-1) 对该位置的前一个节点操作: 
            # 1. 先用node.next -> 原先节点指向的node
            # 2. pre的next -> node
            node.next = pre.next
            pre.next = node
            
    def search(self, item):
        """查找元素"""
        cur = self.__head
        # 循环遍历比较值即可
        while cur != None:
            if cur.data == item:
                return True
        return False
    
    def remove(self, item):
        """删除首次找到的该元素-两个游标"""
        pre = None
        cur = self.__head
        while cur != None:
            if cur.data == item:
                # 判断是否为 head
                if cur == self.__head:
                    self.__head = cur.next
                else:
                    # 删除: pre.next -> cur.next
                    pre.next = cur.next
                break
            else:
               # 移动: pre移动一次, cur也移动一次, 顺序: 必须先移动pre, 才能跟上cur的节奏哦
                pre = cur
                cur = cur.next

# 测试
l = SingleLinkList()

print(l.is_empty())
print(l.length())

l.append(0)
print(l.is_empty())
print(l.length())

for i in range(8):
    l.append(i)

# 头插入一个 666 
l.add(666)

# inset
l.insert(-1, 999)
l.insert(2, 6699)
l.insert(888,999)
l.insert(5,'cj')
# 遍历
l.travel()

l.remove(999)
# l.remove('aaa')
True
0
False
1
999 0 6699 1 2 cj 3 4 5 6 7 999 

l.travel()
0 6699 1 2 cj 3 4 5 6 7 999 

l.remove(999)
l.travel()
0 6699 1 2 cj 3 4 5 6 7 

单链表完整实现

  • object Python3是默认继承的
  • 理解指向在Python中就是"=", 从右往左看
  • 要在头脑中有画面感, 毕竟, "="就是'->'指针呀
class Node:
    """节点类"""
    def __init__(self, data=None):
        self.data = data
        self.next = None
        
class SingleLinkList:
    """单链表类"""
    def __init__(self, node=None):
        """构造链表的头节点"""
        self.__head = node
        
    @property    
    def is_empty(self):
        """链表是否为空"""
        return self.__head == None
    
    @property
    def length(self):
        """链表中元素的个数"""
        current = self.__head
        count = 0 
        while current is not None:
            count += 1 
            # 游标不断向后移动
            current = current.next
        return count
    
    def travel(self):
        """遍历列表元素"""
        current = self.__head
        while current != None:
            print(current.data)
            current = current.next
            
    def append(self, item):
        """尾部插入元素"""
        node = Node(item)
        current = self.__head
        if self.is_empty:
            self.__head = node
        else:
            while current.next is not None:
                current = current.next
            current.next = node
    
    def add(self, item):
        """头部插入元素"""
        node = Node(item)
        if self.is_empty:
            self.__head = node
        else:
            # 插入顺序,脑海里要有画面感
            node.next = self.__head
            self.__head = node

    def insert(self, position, item):
        """从指定位置插入元素"""
        if position <= 0:
            self.add(item)
        elif position > (self.length-1):
            self.append(item)
        else:
            node = Node(item)
            prior = self.__head
            count = 0
            while count < (position-1):
                count += 1
                prior = prior.next
            # 此时prior已定位到当前位置前一个节点
            node.next = prior.next
            prior.next = node
    
    def search(self, item):
        """搜索元素并范围其位置-首次被找到"""
        position = 0 
        current = self.__head
        while current:
            position += 1 
            if current.data == item:
                return position-1
            else:
                # 记得移动游标,不然就死循环了
                current = current.next
        return False
    
    def remove(self, item):
        """删除元素-首次被找到"""
        # 删除: prior.next -> prior.next.next 或者: prior.next = cur.next
#         prior = self.__head
#         position = self.search(item)
#         if position:
#             count = 0
#             while prior:
#                 count += 1
#                 if count == position-1
#                 prior = prior.next
                
#         return 

        # 这里采用: prior.next = cur.next
        prior = None
        current = self.__head
        while current:
            if current.data == item:
                # 判断是否为头节点
                if current == self.__head:
                    self.__head = current.next
                else:
                    prior.next = current.next
                break 
            else:
                # prior先移动一次,到current的位置, 然后current再往后移动一次
                prior = current
                current = current.next

l = SingleLinkList()
l.is_empty
True

l.append(1)
l.add(0)
l.append('cj')
l.insert(999,666)
l.travel()
l.search('cj')
0
1
cj
666

2

l.add(333)
l.travel()
333
333
333
0
1
cj
666

耐心和恒心, 总会获得回报的.

相关教程
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号