【算法】链表

链表基础(Linked list)

定义

链表:是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)

 

链表的基本元素:

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

 

时间复杂度

由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。

 

节点&链表定义

节点定义

#encoding=utf-8
class Node:
    def __init__(self,value = None, next = None):
        self.value = value
        self.next = next
    def __str__(self):
        #测试基本功能,输出字符串
        return str(self.value)

print (Node("text"))

 

链表定义

逐个定义节点,再把每个节点的关系表示出来。

#encoding=utf-8
class Node:
    def __init__(self,value = None, next = None):
        self.value = value
        self.next = next
    def __str__(self):
        return str(self.value) 

#定义每个节点
node1=Node(1)
node2=Node(2)
node3=Node(3)

#定义关系
node1.next=node2
node2.next=node3

  

顺序打印和逆序打印

顺序打印

通过输入第一个节点,循环整个链表,顺序打印整个链表

#encoding=utf-8
class Node:
    def __init__(self,value = None, next = None):
        self.value = value
        self.next = next
    def __str__(self):
        return str(self.value)
 
#定义每个节点
node1=Node(1)
node2=Node(2)
node3=Node(3)

#定义关系
node1.next=node2
node2.next=node3

def printlist(node):
    while node:
        print(node)
        node=node.next

printlist(node1)

  

 

运行结果

1

2

3

 

逆序打印

使用递归的方法打印全部链表元素,顺序为逆序

#encoding=utf-8

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

    def __str__(self):
        return str(self.value)

 
#定义每个节点
node1=Node(1)
node2=Node(2)
node3=Node(3)

#定义关系
node1.next=node2
node2.next=node3

def printBackward(node):
    if node == None:
        return

    head = node
    tail= node.next
    printBackward(tail)
    print (head,tail)

 
printBackward(node1)

 
运行结果

3 None

2 3

1 2

 

 

计算链表的长度

#encoding=utf-8

class Node(object):#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next

    def __str__(self):
        return self.data

 
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

node1.next = node2
node2.next = node3
 
class LinkedList(object):

    def __init__(self, head = None):
        self.head = head

    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter


print(len(LinkedList(node1)))

运行结果

3

  

在链表中插入数据

从链表的前面插入数据 

步骤:

  • 被插入数据为空,返回
  • 使用该输入数据创建一个节点,并将该节点的next指向原来头节点
  • 设置该节点为头节点

 

代码实现:

#encoding=utf-8
class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next
    def __str__(self):
        return self.data 

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
 

node1.next = node2
node2.next = node3 

class LinkedList(object): 

    def __init__(self, head = None):
        self.head = head

    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter

 
    def insertToFront(self, data):
        # 功能:输入data,插入到头节点前,并更改为头节点
        # 输出:当前头节点
        if data is None:
            return None
        node = Node(data, self.head)
        self.head = node
        return node

node4 = Node(4)
link_list = LinkedList(node1)#创建一个链表实例,链表从node1开始
link_list.insertToFront(node4)
print(len(link_list))

 
运行结果

4

  

 

从链表的后面插入数据

步骤

  • 若输入数据为空,返回None
  • 若头节点为空,直接将输入数据作为头节点
  • 若非空,则遍历整个链表,直到当前节点的下一个节点为None时,将当前节点的下一个节点设置为输入数据

 

代码实现:

#encoding=utf-8
class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next

    def __str__(self):
        return self.data 

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

node1.next = node2
node2.next = node3 

class LinkedList(object):
    def __init__(self, head = None):
        self.head = head
    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter

    def insertToFront(self, data):
        # 功能:输入data,插入到头节点前,并更改为头节点
        # 输出:当前头节点
        if data is None:
            return None
        node = Node(data, self.head)
        self.head = node
        return node

    def append(self, data):
        # 功能:输入data,作为节点插入到末尾
        if data is None:
            return None
        node = Node(data)
        if self.head is None:
            self.head = node
            return node
        curr_node = self.head
        while curr_node.next is not None:
            curr_node = curr_node.next
        curr_node.next = node
        return node 

node4 = Node(4)
link_list = LinkedList(node1)
link_list.append(node4)

print(len(link_list))

  

在链表的中间插入数据

#encoding=utf-8
class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next
    def __str__(self):
        return str(self.data) 

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
 
node1.next = node2
node2.next = node3
 
class LinkedList(object):
     def __init__(self, head = None):
        self.head = head

    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
            return counter

    def insertToFront(self, data):
        # 功能:输入data,插入到头节点前,并更改为头节点
        # 输出:当前头节点
        if data is None:
            return None
        node = Node(data, self.head)
        self.head = node
        return node

    def append(self, data):
        # 功能:输入data,作为节点插入到末尾
        if data is None:
            return None
        node = Node(data)        
        if self.head is None:
            self.head = node
            return node
        curr_node = self.head
        while curr_node.next is not None:
            curr_node = curr_node.next
        curr_node.next = node
        return node

    def insertAmong(self,data,site):
        #功能:输入data,插到指定site前。
        #输出:插入的data
        if data is None:
            return None
        if self.head is None:
            return None
        if site is None:
            return None
        node = Node(data)
        curr_node = self.head
        while curr_node.next is not None:
            if curr_node.next.data==site:
                tmp=curr_node.next
                curr_node.next=node
                node.next=tmp
                return node
            else:
                curr_node=curr_node.next 
        return 'insert fail'


link_list = LinkedList(node1)
print(link_list.insertAmong(5,2))
print(len(link_list )

  

在链表中查找元素

#encoding=utf-8
class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next

    def __str__(self):
        return str(self.data)

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

node1.next = node2
node2.next = node3

class LinkedList(object):

    def __init__(self, head = None):
        self.head = head
    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter

    def insertToFront(self, data):
        # 功能:输入data,插入到头节点前,并更改为头节点
        # 输出:当前头节点
        if data is None:
            return None
        node = Node(data, self.head)
        self.head = node
        return node

    def append(self, data):
        # 功能:输入data,作为节点插入到末尾
        if data is None:
            return None
        node = Node(data)
        if self.head is None:
            self.head = node
            return node
        curr_node = self.head
        while curr_node.next is not None:
            curr_node = curr_node.next
        curr_node.next = node
        return node


    def find(self, data):
        # 功能:查找链表的节点data与data相同的节点
        if data is None:
            return None
        curr_node = self.head
        while curr_node is not None:
            if curr_node.data == data:
                return curr_node
            curr_node = curr_node.next
        return None

link_list = LinkedList(node1)
print(link_list.find(2))

  

删除元素

只定义一个变量作为当前节点,使用它的下一个节点去判断是否与数据数据匹配,若匹配,直接将当前节点指向下下一个节点。

#encoding=utf-8
class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next

    def __str__(self):
        return str(self.data)

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

node1.next = node2
node2.next = node3

class LinkedList(object):

    def __init__(self, head = None):
        self.head = head
    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter

    def insertToFront(self, data):
        # 功能:输入data,插入到头节点前,并更改为头节点
        # 输出:当前头节点
        if data is None:
            return None
        node = Node(data, self.head)
        self.head = node
        return node

    def append(self, data):
        # 功能:输入data,作为节点插入到末尾
        if data is None:
            return None
        node = Node(data)
        if self.head is None:
            self.head = node
            return node
        curr_node = self.head
        while curr_node.next is not None:
            curr_node = curr_node.next
        curr_node.next = node
        return node


    def find(self, data):
        # 功能:查找链表的节点data与data相同的节点
        if data is None:
            return None
        curr_node = self.head
        while curr_node is not None:
            if curr_node.data == data:
                return curr_node
            curr_node = curr_node.next
        return None


    def deleteData(self,data):
        # 只定义一个变量来完成删除操作
        if data is None:
            return
        if self.head is None:
            return
        if self.head.data == data:
            self.head = self.head.next
            return
        curr_node = self.head
        while curr_node.next is not None:
            if curr_node.next.data == data:
                curr_node.next = curr_node.next.next
                return
            curr_node = curr_node.next
            
link_list = LinkedList(node1)
print(link_list.deleteData(2))
print(len(link_list ))

  

 PS:包含全部功能的代码

#encoding=utf-8
class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next

    def __str__(self):
        return str(self.data)

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

node1.next = node2
node2.next = node3

class LinkedList(object):

    def __init__(self, head = None):
        self.head = head
    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter

    def insertToFront(self, data):
        # 功能:输入data,插入到头节点前,并更改为头节点
        # 输出:当前头节点
        if data is None:
            return None
        node = Node(data, self.head)
        self.head = node
        return node

    def append(self, data):
        # 功能:输入data,作为节点插入到末尾
        if data is None:
            return None
        node = Node(data)
        if self.head is None:
            self.head = node
            return node
        curr_node = self.head
        while curr_node.next is not None:
            curr_node = curr_node.next
        curr_node.next = node
        return node

    def insertAmong(self,data,site):
        #功能:输入data,插到指定site前。
        #输出:插入的data
        if data is None:
            return None
        if self.head is None:
            return None
        if site is None:
            return None
        node = Node(data)
        curr_node = self.head
        while curr_node.next is not None:
            if curr_node.next.data==site:
                tmp=curr_node.next
                curr_node.next=node
                node.next=tmp
                return node
            else:
                curr_node=curr_node.next
        return 'insert fail'

    def printList(self):
        #功能:顺序打印链表。将链表顺序储存在一个list中。
        l=[]
        curr = self.head
        while curr:
            l.append(curr.data)
            curr=curr.next
        return l


    def find(self, data):
        # 功能:查找链表的节点data与data相同的节点
        if data is None:
            return None
        curr_node = self.head
        while curr_node is not None:
            if curr_node.data == data:
                return curr_node
            curr_node = curr_node.next
        return None


    def deleteData(self,data):
        # 只定义一个变量来完成删除操作
        if data is None:
            return
        if self.head is None:
            return
        if self.head.data == data:
            self.head = self.head.next
            return
        curr_node = self.head
        while curr_node.next is not None:
            if curr_node.next.data == data:
                curr_node.next = curr_node.next.next
                return
            curr_node = curr_node.next
    
link_list = LinkedList(node1)
print(link_list.insertAmong(5,2))
print(len(link_list ))
print(link_list.printList())

  

 

posted @ 2018-10-11 18:22  LiliP  阅读(288)  评论(0编辑  收藏  举报