链表(python实现)

链表(Linked List)

很多的教材都是用C语言实现链表,因为c有指针,可以很方便的控制内存,很方便就实现链表,其他的语言,则没那么方便,由于python是动态语言,可以直接把对象赋值给新的变量,于是在python一切皆为对象的原理上实现链表的各项操作。

在实现链表python类的属性和方法操作之前,先整理一些链表的理论知识。

一、链表的基本结构

链表是通过一个个节点(Node)组成的,每个节点都包含了称为数据域(value)和指针域(next)的基本单元,它也是一种递归的数据结构。它能保持数据之间的逻辑顺序,但存储空间不必按照顺序存储。 

链表的基本元素有:

  • 节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。
  • head:head节点永远指向第一个节点
  • tail: tail永远指向最后一个节点
  • None:链表中最后一个节点的指针域为None值

二、链表的种类以及和动态数组(Array List)的对比

 

三、单向链表属性与各类操作方法代码

from util.Empty import Empty
from util.Outbound import Outbound

#先定一个node的类
class Node:                  #value + next
    def __init__ (self, value = None, next = None):
        self.value = value
        self.next = next

#各类链表的操作方法
class LinkedList:
    def __init__(self):      #定义一开始是空的属性
        self.head = Node()
        self.tail = None
        self.length = 0

    def peek(self):
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        return self.head.next

    def get_first(self):
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        return self.head.next
        
    def get_last(self):
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        node = self.head
        while node.next != None:
            node = node.next
        return node
    
    def get(self, index):
        if (index < 0 or index >= self.length):
            raise Outbound( 'index is out of bound' );
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        node = self.head.next
        for i in range(index):
            node = node.next
        return node
                
    #加入到原node前面:O(1)
    def add_first(self, value):
        node = Node(value, None)      #create一个node(为了插进一个链表)
        node.next = self.head.next    #先连后一个的value
        self.head.next = node         #再连上一个的next
        self.length += 1              
    
    #加入在原node后面:O(n)
    def add_last(self, value):
        new_node = Node(value)
        node = self.head
        while node.next != None:
            node = node.next
        node.next = new_node
        self.length += 1

    def add(self, index, value):
        if (index < 0 or index > self.length):
            raise Outbound( 'index is out of bound' )
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        new_node = Node(value)
        node = self.head
        for i in range(index):
            node = node.next
        new_node.next = node.next;
        node.next = new_node;
        self.length += 1     
    
    # O(1)
    def remove_first(self):
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        value = self.head.next
        self.head.next = self.head.next.next
        self.length -= 1
        return value    
    
    #O(n)    
    def remove_last(self):
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        node = self.head.next
        prev = self.head
        while node.next != None:
            prev = node
            node = node.next
        prev.next = None
        return node.value
    
    #O(n)
    def remove(self, index):
        if (index < 0 or index >= self.length):
            raise Outbound( 'index is out of bound' );
        if not self.head.next:
            raise Empty( 'LinkedList is empty' )
        node = self.head
        for i in range(index):
            node = node.next
        result = node.next;
        node.next = node.next.next;
        self.length += 1     
        return result;      
    
    #O(n)
    def printlist(self):
        node = self.head.next
        count = 0
        while node and count<20:
            print(node.value, end = " ")
            node = node.next
            count = count + 1
        print('')
ll = LinkedList()
for i in range(1, 10):
    ll.add_last(i)
    #ll.add_end(i+1)

mm = LinkedList()
for i in range(100, 110):
    mm.add_last(i)
    #ll.add_end(i+1)        

ll.printlist()
mm.printlist()

#输出结果
1 2 3 4 5 6 7 8 9 
100 101 102 103 104 105 106 107 108 109 
ll.add_first(0)    
ll.add_first(-1)
print('Linked List: ')
ll.printlist()
'''  Linked List: 
    -1 0 1 2 3 4 5 6 7 8 9  '''

node = ll.peek()
print('peek: ' , str(node.value))                #peek:  -1
node = ll.get_first()
print('get first: ' , str(node.value))           #get first:  -1  
node = ll.get_last()
print('get last: ' , str(node.value))            #get last:  9
node = ll.get(0)
print('get position 0: ' , str(node.value))     #get position 0:  -1
node = ll.get(2)
print('get position 2: ' , str(node.value))     #get position 2:  1
ll.add(0, -2)
ll.add(4, 1.5)
print('Linked List: ')       
'''  Linked List: 
     -2 -1 0 1 1.5 2 3 4 5 6 7 8 9    '''

ll.printlist()
node = ll.remove(0)
print('remove position 0: ' , str(node.value))
ll.printlist()
node = ll.remove(3)
print('remove position 3: ' , str(node.value))
ll.printlist()
'''
remove position 0:  -2
-1 0 1 1.5 2 3 4 5 6 7 8 9 
remove position 3:  1.5
-1 0 1 2 3 4 5 6 7 8 9 
'''

ll = LinkedList()
for i in range(1, 4):
    ll.add_first(i)
    #ll.add_end(i+1)
print('Linked List: ')
ll.printlist()
ll.remove_first()
ll.remove_first()
print('Linked List: ')
ll.printlist()
ll.remove_first()
print('Linked List: ')
ll.printlist()

ll = LinkedList()
for i in range(1, 10):
    ll.add_last(i)

ll.remove_first()
ll.remove_last()
ll.remove_first()
ll.remove_last()
print('Linked List: ')
ll.printlist()

'''
Linked List: 
3 2 1 
Linked List: 
1 
Linked List: 

Linked List: 
3 4 5 6 7 
'''

四、操作链表的原理知识

1.遍历链表

    链表的基本操作:遍历next节点 

  • 在列表中查找一个元素 
  • 在列表中插入一个元素
  • 从列表中删除一列元素

    不可以用head来遍历列表 

  • 否则会丢失列表的一些节点 
  • 可以使用和head相同类型的索引变量:current

2.插入

3.删除

4.双向链表

5.循环链表

猜你喜欢

转载自www.cnblogs.com/kumata/p/9147077.html
今日推荐