Q1 C语言中实现单链表需要用到结构体,python中如何实现?
Q2 面向过程和面向对象实现一个单链表到底有什么不同的感受?
1、定义单链表
2、单链表的实现
3、单链表的方法
4、单链表和顺序表的区别
Q3 python中实现链表的时候,为什么要定义两个类Node一个SingleList
Q4 current和current.next 分别代表什么?
Q5 什么时候用current?什么时候用current.next?
A1
typedef struct node { ElemType data; struct node *next; }Node, *LinkList;
但是刚学完python如何实现这个节点呢?用类,造一个出来
class Node: def __init__(self, data): self.data = data self.next = None
C语言中用如下方法表示创建好了一个链表L
LinkList L = (LinkList)malloc(sizeof(Node)); L->next = NULL
class SingleList: """实现单链表""" def __init__(self, node=None): self._head = node my_list = SingleList()
图片由python Tutor生成
A3
为什么要创建两个类呢?因为最终的操作是只用链表这个对象去操作里面的节点,节点是一个对象,需要一个类,链表也是个对象,也需要个类。
'''判断链表是否为空''' def is_empty(self): return self._head is None
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 is not None: print("{0}".format(current.data), end=" ") current = current.next print(" ")
'''在链表头部插入节点,头插法''' def add(self, item): node = Node(item) if self.is_empty(): self._head = node else: node.next = self._head self._head = node
'''在链表尾部插入元素,尾插法''' def append(self, item): node = Node(item) if self.is_empty(): self._head = node else: current = self._head while current.next is not None: current = current.next current.next = node
6.insert
''' 在某个位置插入链表 两个特殊位置 1、在0位置 add 2、在最后一个位置 append 在插入一个节点的时候需要考虑当前位置的前一个节点。 ''' def insert(self, item, pos): if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: node = Node(item) pre = self._head count = 0 while count < (pos - 1): pre = pre.next count += 1 node.next = pre.next pre.next = node
''' 删除节点 需要注意如果删除的节点就是第一个怎么操作? ''' def remove(self, item): current = self._head if self.is_empty(): return elif current.data == item: self._head = current.next else: previous = None while current is not None and current.data != item: previous = current current = current.next previous.next = current.next
'''查找链表中的节点''' def search(self, item): found = False if self.is_empty(): return found else: current = self._head while current is not None and not found: if current.data == item: found = True else: current = current.next return found
8.实现上面操作
if __name__ == "__main__": my_list = SingleList() print("add操作:") my_list.add(98) my_list.add(99) my_list.travel() print("{:#^50}".format("")) print("append操作:") my_list.append(100) my_list.append(101) my_list.append(102) my_list.append(103) my_list.travel() print("{:#^50}".format("")) print("insert操作:") my_list.insert(99, 0) my_list.insert(104, 10) my_list.insert(19, 3) my_list.insert(56, 5) my_list.travel() print("{:#^50}".format("")) print("remove操作:") my_list.remove(19) my_list.remove(56) my_list.travel() print("{:#^50}".format("")) print("search操作:") print(my_list.search(1000)) print(my_list.search(101)) print("链表长为:{0}".format(my_list.length()))
操作 | 链表时间 | 顺序表时间 |
---|---|---|
表头插入元素add | O(1) | O(n) |
表尾插入元素append | O(n) | O(1) |
在任意位置插入元素insert | O(n) | O(n) |
访问元素 | O(n) | O(1) |
A4 和 A5
current指的是当前整个节点,而current.next指的是下一个节点的地址
图片由python Tutor生成
用两个函数来测试分别用current和current.next做while循环终止条件,count遍历了多少次,我猜测是用current 比 current.next 的count要多一次。
def traverse_next(self): current = self._head count = 0; if self.is_empty(): return count else: while current.next is not None: count += 1 current = current.next return count def traverse(self): current = self._head count = 0 if self.is_empty(): return count else: while current is not None: count += 1 current = current.next return count
和我的猜测一样,current—>7 , current.next —> 6
将上述代码修改为如下,加上一个返回current.data。会发生什么?
def traverse_next(self): current = self._head count = 0; if self.is_empty(): return count else: while current.next is not None: count += 1 current = current.next return count,current.data def traverse(self): current = self._head count = 0 if self.is_empty(): return count else: while current is not None: count += 1 current = current.next return count, current.data
代码结果表明:虽然current和current.next 都能当遍历的条件,但是current.next可以返回尾结点的数值域,而current将一整个节点遍历完,最后current = None了,当调用current.data自然会报错。
用append()在表尾增加元素和遍历单链表说明什么时候用current和什么时候用current.next
'''在链表尾部插入元素,尾插法''' def append(self, item): node = Node(item) if self.is_empty(): self._head = node else: current = self._head while current.next is not None: current = current.next current.next = node def append2(self,item): node = Node(item) if self.is_empty(): self._head = node else: current = self._head previous = None while current is not None: previous = current current = current.next previous.next = node '''遍历单链表''' def travel(self): current = self._head while current is not None: print("{0}".format(current.data), end=" ") current = current.next print(" ") def travel2(self): current = self._head while current.next is not None: print("{0}".format(current.data), end=" ") current = current.next print(" ") if __name__ == "__main__": my_list = SingleList() my_list.append(100) my_list.append(101) my_list.append(102) my_list.append(103) my_list.append2(104) print("用current当循环的条件:") my_list.travel() print("{:#^50}".format("")) print("用current.next当循环的条件:") my_list.travel2() print(my_list.length())
在向表尾添加元素的时候用current.next方便,遍历链表用current,用current.next会少表尾最后一个元素。
A2
由面向过程的C语言和面向对象的python去实现一个链表的感受: