单链表及其基本操作

  链表是最基本的数据结构,很多高级的数据结构都离不开链表的身影,本文从最基本的链表实现开始,逐步实现对单链表的判空、求长度、遍历、添加、删除等操作。

1.定义链表节点

  链表是由一个个数据节点连接而成,首先需要构建数据节点,包含数据元素elem和指向下一节点的next。

1 class Node(object): 
2     """首先定义节点类"""
3     def __init__(self, element):  # 构建数据节点时,需要传入数据元素element
4         self.elem = element
5         self.next = None  # 由于一开始next节点不知道指向什么地方,所以就设置为空

2.初始化单链表

  初始化链表时,需要一个对象属性指向头结点。

1 class SingleLinkList(object):
2     """定义单链表类"""
3     def __init__(self, node = None):  # 构建链表时,需要传入数据节点node,node默认为None
4         self. __head = node  # head是私有属性

3.单链表基本操作

3.1.链表判空

  空链表的头一定是指向None的。

1     def is_empty(self):
2         """链表是否为空"""
3         return self.__head is None

3.2.求链表长度

  求链表长度就是统计链表节点的个数,可以使用一个游标cur遍历节点,使用一个计数器count记录节点个数。

1     def length(self):
2         """链表长度"""
3         cur = self.__head
4         count = 0
5         while cur is not None:
6             count += 1
7             cur = cur.next
8         return count

3.3.遍历链表

1     def travel(self):
2         """遍历链表"""
3         cur = self.__head
4         while cur is not None:
5             print(cur.elem, end=" ")  # end=" "关闭换行功能,print的原型默认是以end="\n"结尾.
6             cur = cur.next
7         print(end="\n")

3.4.往链表头部添加元素

  往链表中添加元素就相当远添加数据节点,需要传入节点的数据。

  Tips_1:增删链表时,A=B可以被理解为,使A指向B;

  Tips_2:增删链表时,需要先保证不破坏原有链表的链接,以保证操作的顺序正确,如需要先node.next = self.__head,再self.__head = node。

1     def add(self, item):
2         """在链表头部添加元素"""
3         node = Node(item)
4         node.next = self.__head
5         self.__head = node

3.5.往链表尾部添加元素

 1     def append(self, item):
 2         """链表尾部添加元素"""
 3         node = Node(item)
 4         if self.is_empty():
 5             self.__head = node
 6         else:
 7             cur = self.__head
 8             while cur.next is not None:
 9                 cur = cur.next
10             cur.next = node

3.6.往链表指定位置添加元素

  需要考虑添加位置的边界条件:如果添加的位置是链表头部,可以直接调用add()函数。如果添加的位置是链表尾部,可以直接调用append()函数。

 1     def insert(self, pos, item):
 2         """在指定位置添加元素"""
 3         if pos <= 0:
 4             self.add(item)
 5         elif pos > self.length()-1:
 6             self.append(item)
 7         else:
 8             node = Node(item)
 9             prev = self.__head
10             count = 0
11             while count < (pos-1):
12                 count += 1
13                 cur = cur.next
14             node.next = cur.next
15             cur.next = node

3.7.删除节点

  链表被打断后,需要pre记录断点前的链表部分。

 1     def remove(self, item):
 2         """删除节点"""
 3         cur = self.__head
 4         pre = None  
 5         while cur is not None:
 6             if cur.elem == item:
 7                 if cur == self.__head:  # 头节点特殊处理
 8                     self.__head = cur.next
 9                 else:
10                     pre.next = cur.next
11                 break
12             else:
13                 pre = cur
14                 cur = cur.next

3.8.查找节点

1     def search(self, item):
2         """查找节点是否存在"""
3         cur = self.__head
4         while cur is not None:
5             if cur.elem == item:
6                 return True
7             else:
8                 cur = cur.next
9         return False

3.9.测试与结果

 1 # 测试
 2 if __name__ == "__main__":
 3     li = SingleLinkList()
 4     print(li.is_empty())       # True
 5     print(li.length())         # 0
 6 
 7     li.append(1)
 8     print(li.is_empty())       # False
 9     print(li.length())         # 1
10 
11     li.append(2)
12     li.add(8)
13     li.append(3)
14     li.append(4)
15     li.append(5)
16     li.append(6)
17     li.insert(-1, 9)  
18     li.insert(2, 100)  
19     li.insert(10, 200) 
20     li.travel()                # 9 8 100 1 2 3 4 5 6 200
21 
22     li.remove(100)
23     li.travel()                # 9 8 1 2 3 4 5 6 200
24     li.remove(9)  
25     li.travel()                # 8 1 2 3 4 5 6 200 
26     li.remove(200)  
27     li.travel()                # 8 1 2 3 4 5 6
posted @ 2020-05-24 18:58  孔子?孟子?小柱子!  阅读(154)  评论(0编辑  收藏  举报