链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

  • 优点: 真正的动态 不需要处理容量的问题
  • 缺点:不能随机访问

    链表实现

    ```python class Node: def init(self,value,next=None) -> None:
    1. self._value = value
    2. self._next = next

class LinkedList: def init(self) -> None:

  1. # 虚拟头结点
  2. self.__dummyhead = Node(value=None,next=None)
  3. self.__size = 0
  4. # 获取链表长度
  5. def get_size(self):
  6. return self.__size
  7. # 判断链表是否为空
  8. def is_empty(self):
  9. return self.__size == 0
  10. # 链表头部添加元素
  11. def add_first(self,value):
  12. # # 创建新节点
  13. # node = Node(value=value)
  14. # # 当前节点的next执行之前的head节点
  15. # node.__next = self.__head
  16. # # 改变head的指向
  17. # self.__head = node
  18. # self.__head = Node(value=value,next=self.__head)
  19. # self.__size +=1
  20. self.add(0,value)
  21. def add(self,index:int,value):
  22. assert index>=0 and index<=self.__size, " index error"
  23. node_prev = self.__dummyhead
  24. for i in range(self.__size):
  25. node_prev = node_prev._next
  26. # node_prev_next = node_prev.__next
  27. # node = Node(value=value)
  28. # node_prev.__next = node
  29. # node.__next = node_prev_next
  30. node_prev._next = Node(value=value,next=node_prev._next)
  31. self.__size +=1
  32. # 尾部添加元素
  33. def addLast(self,value):
  34. self.add(self.__size,value)
  35. # 获取链表元素
  36. def get(self,index):
  37. cur = self.__dummyhead._next
  38. for i in range(index):
  39. cur = cur._next
  40. return cur._value
  41. # 获取链表第一个元素
  42. def get_first(self):
  43. return self.get(0)
  44. # 获取链表末尾元素
  45. def get_last(self):
  46. return self.get(self.__size -1 )
  47. # 修改下标为index的值为 value
  48. def set(self,index,value):
  49. cur = self.__dummyhead._next
  50. for i in range(index):
  51. cur = cur._next
  52. cur._value = value
  53. # 查看链表中是否存在某个元素
  54. def contains(self,value) ->bool:
  55. cur = self.__dummyhead._next
  56. while (cur is not None):
  57. if cur._value == value:
  58. return True
  59. else:
  60. cur = cur._next
  61. return False
  62. # 删除指定位置的元素
  63. def remove(self,index):
  64. assert index>=0 and index<self.__size ," index error"
  65. cur = self.__dummyhead
  66. for i in range(index):
  67. cur = cur._next
  68. del_node = cur._next
  69. cur._next = del_node._next
  70. del_node.next = None
  71. self.__size -=1
  72. return del_node
  73. # 删除链表头元素
  74. def remove_first(self):
  75. return self.remove(0)
  76. # 删除链表尾元素
  77. def remove_last(self):
  78. return self.remove(self.__size -1 )
  79. def __str__(self) -> str:
  80. strs = "dummyhead -> "
  81. cur = self.__dummyhead._next
  82. while (cur is not None):
  83. strs += f"{cur._value} -> "
  84. cur = cur._next
  85. return strs + "None"
  1. <a name="GP2yv"></a>
  2. ## 时间复杂度分析
  3. - 添加 :<br />add_first O(1)<br />add_last O(n)<br />add_index (n/2) O(n)<br />
  4. - 删除 :<br />remove_first O(1)<br />remove_last O(n)<br />remove_index (n/2) O(n)
  5. - 查找 修改 O(n)
  6. <a name="VFjBB"></a>
  7. ## 链表实现栈
  8. 用链表实现栈,可以理解为始终在链表头部添加元素(入栈)和在头部删除元素(出栈),这样在实现后其入栈和出栈操作的时间复杂度都为O(1)
  9. ```python
  10. import abc
  11. class Stack(metaclass=abc.ABCMeta):
  12. @abc.abstractmethod
  13. def pop(self):
  14. pass
  15. @abc.abstractmethod
  16. def push(self, item):
  17. pass
  18. @abc.abstractmethod
  19. def clear(self):
  20. pass
  21. @abc.abstractmethod
  22. def empty(self):
  23. pass
  24. @abc.abstractmethod
  25. def size(self):
  26. pass
  27. @abc.abstractmethod
  28. def top(self):
  29. pass
  30. @abc.abstractmethod
  31. def show(self):
  32. pass
  33. class LinkedListStack(Stack):
  34. def __init__(self):
  35. self.__data = LinkedList()
  36. def push(self, item):
  37. """ 入栈 """
  38. self.__data.add_first(item)
  39. def empty(self):
  40. """ 判断是否为空栈 """
  41. return self.__data.is_empty()
  42. def size(self):
  43. """ 输出栈的大小 """
  44. return self.__data.get_size()
  45. def pop(self):
  46. """ 出栈 """
  47. assert self.size() > 0, "stack is empty"
  48. return self.__data.remove_first()
  49. def top(self):
  50. """ 查看栈顶值 """
  51. assert self.size() > 0, "stack size is 0"
  52. return self.__data.get_first()
  53. def clear(self):
  54. """ 清空栈 """
  55. del self.__data
  56. def show(self):
  57. str_start = "top ["
  58. node = self.__data.dummyhead.next
  59. for i in range(self.__data.get_size()):
  60. if i == self.__data.get_size() - 1:
  61. str_start += str(node.value)
  62. else:
  63. str_start += str(node.value) + ","
  64. node = node.next
  65. str_start += "]"
  66. print(str_start)

链表实现队列

在链表基础上实现队列其入队操作可以在链表头部进行操作,因为在链表头部删除一个元素的时间复杂度时O(1),在引入尾节点后对其在尾节点的添加操作时间复杂度可以优化到O(1)。因为队列基本的操作就是入队和出队两个操作。所以使用上处队列(使用链表实现)时间复杂度可以优化到O(1)。

  1. """
  2. 链表实现队列
  3. """
  4. class Node:
  5. def __init__(self, value, next=None) -> None:
  6. self._value = value
  7. self._next = next
  8. class LinkedListQueue:
  9. """
  10. 使用链表实现队列 - 链表尾部进行入队操作 链表头部实现出队操作
  11. """
  12. def __init__(self) -> None:
  13. # 虚拟头结点
  14. self.__head = None
  15. self.__size = 0
  16. self.__tail = None
  17. # 获取链表长度
  18. def get_size(self):
  19. return self.__size
  20. # 判断链表是否为空
  21. def is_empty(self):
  22. return self.__size == 0
  23. def enqueue(self, value):
  24. # tail指向尾节点
  25. if self.__tail is None:
  26. self.__tail = Node(value=value)
  27. self.__head = self.__tail
  28. else:
  29. self.__tail._next = Node(value=value)
  30. self.__tail = self.__tail._next
  31. self.__size += 1
  32. def dequeue(self) -> Node:
  33. # 出队操作
  34. assert self.is_empty(), " queue is empty"
  35. ret_node = self.__head
  36. self.__head = self.__head._next
  37. ret_node._next = None
  38. if self.__head is None:
  39. self.__tail = None
  40. self.__size -= 1
  41. return ret_node
  42. def get_front(self):
  43. assert self.is_empty(), " queue is empty"
  44. return self.__head
  45. def __str__(self):
  46. str_s = "Queue front"
  47. node = self.__head
  48. for i in range(self.get_size()):
  49. str_s +=f" <- {node._value} "
  50. node = node._next
  51. str_s +=" None <- tail"
  52. return str_s