Python数据结构与算法3-链表2

  • 双链表
    拥有两个链接,分别指向前驱节点后继节点

定义双链表节点

# 定义节点
class Node(object):
    def __init__(self, node = None):
        self.elem = node
        self.prev = None
        self.next = None

双链表操作实现:

# 构造双链表
class DoubleLinkedList(object):
    def __init__(self, node = None):
        self.__head = node
        
    def is_empty(self):
        '''链表是否为空'''
        return self.__head == None
    
    def length(self):
        '''链表长度'''
        cur = self.__head
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count 
    
    def travel(self): 
        '''遍历整个链表'''
        cur = self.__head
        while cur != None:
            print(cur.elem, end = " ")
            cur = cur.next
        print("")
    
    def add(self, item):
        '''链表头部添加元素,头插法'''
        node = Node(item)
        # 先将新节点后继链接指向原首节点,原首节点前驱链接指向新节点
        node.next = self.__head
        node.next.prev = node  
        # 再讲头指针指向新节点
        self.__head = node
    
    def append(self, item):
        '''链表尾部添加元素, 尾插法'''
        node = Node(item)
        if self.is_empty():
            self.__head = node
            
        else:
            cur = self.__head
            while cur.next != None:
                # 移动到最后一个节点处
                cur = cur.next
            # 连接新节点到末尾
            cur.next = node
            node.prev = cur
    
    def insert(self, pos, item):
        '''指定位置添加元素'''
        if pos <= 0:
            # 当pos<=0时,认为是在头部添加.
            self.add(item)
            
        elif pos > self.length()-1:
            # 当pos大于总长度时,认为是在尾部添加
            self.append(item)
            
        else:
            node = Node(item)
            cur = self.__head
            count = 0
            #指针移动到插入位置当前节点处
            while count < pos:
                count += 1
                cur = cur.next

            node.next = cur
            node.prev = cur.prev
            cur.prev.next = node
            cur.prev = node
    
    def remove(self, item):
        '''删除节点'''
        cur = self.__head
        while cur != None:
            if cur.elem == item:
                if cur == self.__head:
                    # 如果删除元素在头节点,头指针指向头节点后继节点
                    self.__head = cur.next
                    if cur.next:
                        # 判断cur.next是否为空,否则将新的首节点的前驱指针置为空值。
                        cur.next.prev = None
                
                else:
                    # 如果在其他位置上,该节点的前驱节点指针直接与该节点的后继节点连接
                    cur.prev.next = cur.next
                    if cur.next:
                        # 判断是否为最后一个元素
                        cur.next.prev = cur.prev
                break
            else:
                cur = cur.next
                
    
    def search(self, item):
        '''查找节点是否存在'''
        cor = self.__head
        while cor != None:
            if cor.elem == item:
                return True
            else:
                cor = cor.next
        return False
  • 单项循环链表
    与单链表类似,但尾节点指向头节点,而非空值。

    节点构造与单链表相同。

    单项循环链表操作实现:

# 构造单向循环链表
class SingleLinkedList(object):
    def __init__(self, node = None):
        self.__head = node
        if node:
            # 若设置起始节点,则起始节点指向自己
            node.next = self.__head
        
    def is_empty(self):
        '''链表是否为空'''
        return self.__head == None
    
    def length(self):
        '''链表长度'''
        cur = self.__head
        if self.is_empty():
            # 若链表为空,返回0
            return 0
        count = 1
        while cur.next != self.__head:
            count += 1
            cur = cur.next
        return count 
    
    def travel(self): 
        '''遍历整个链表'''
        cur = self.__head
        if self.is_empty():
            # 若链表为空,返回空值
            return
        while cur.next != self.__head:
            print(cur.elem, end = " ")
            cur = cur.next
        # 退出循环时,cur停留在尾节点,且未打印。
        print(cur.elem)
        print("")
    
    def add(self, item):
        '''链表头部添加元素,头插法'''
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = self.__head
        else:
            # 找到尾节点
            cur = self.__head
            while cur.next != self.__head:
                cur = cur.next
            # 先将新节点指向第一个节点
            node.next = self.__head
            # 再讲头指针指向新节点
            self.__head = node
            # 尾节点指向新节点
            cur.next = node

    def append(self, item):
        '''链表尾部添加元素, 尾插法'''
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = self.__head
            
        else:
            # 找到尾节点
            cur = self.__head
            while cur.next != self.__head:
                cur = cur.next
            cur.next = node
            node.next = self.__head
    
    def insert(self, pos, item):
        '''
        指定位置添加元素
        与单链表相同
        '''
        if pos <= 0:
            # 当pos<=0时,认为是在头部添加.
            self.add(item)
            
        elif pos > self.length()-1:
            # 当pos大于总长度时,认为是在尾部添加
            self.append(item)
            
        else:
            node = Node(item)
            pre = self.__head
            count = 0
            #指针移动到插入位置前一个节点处
            while count < pos-1:
                count += 1
                pre = pre.next

            node.next = pre.next
            pre.next = node
    
    def remove(self, item):
        '''删除节点'''
        if self.is_empty():
            return
        else:
            cur = self.__head
            pre = None
            while cur.next != self.__head:
                if cur.elem == item:
                    if not pre:
                        # 1.头节点,找到尾节点
                        rear = self.__head
                        while rear.next != self.__head:
                            rear = rear.next
                        self.__head = cur.next
                        # 尾节点重新指向新的首节点
                        rear.next = self.__head

                    else:
                        # 2.中间节点,前节点指针直接指向现节点的后继节点
                        pre.next = cur.next
                    return
                else:
                    pre = cur
                    cur = pre.next
        
            if cur.elem == item:
                if cur == self.__head:
                    # 3.链表只有一个元素
                    self.__head = None
                else:
                    # 4.尾节点
                    pre.next = self.__head
                
                
    
    def search(self, item):
        '''查找节点是否存在'''
        if self.is_empty():
            return False
        else:
            cur = self.__head
            while cur.next != self.__head:
                if cur.elem == item:
                    return True
                else:
                    cur = cur.next
        # 判断尾节点
        return cur.elem == item

你可能感兴趣的:(Python数据结构与算法,数据结构,算法,链表)