欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

python数据结构-双向链表-单向循环链表-栈-队列

时间:2023-08-21
双向链表

双向链表:每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时, 指向空值。

操作

is_ empty()        链表是否为空
length()        链表长度
travel()        遍历链表
add(item)        链表头部添加
append(item)        链表尾部添加
insert(pos, item)        指定位置添加
remove(item)        删除节点
search(item)        查找节点是否存在

实现

# coding:utf-8class Node(object): '''结点点''' def __init__(self, item): self.elem = item self.next = None self.prev = Noneclass DoublelinkList(object): '''双链表''' def __init__(self,node=None): self._head = node def is_empty(self): '''链表是否为空''' return self._head is None def length(self): '''链表长度''' # cur游标, 用来移动遍历节点 cur = self._head # count记录数量 count = 0 while cur != None: count += 1 cur = cur.next return count def travel(self): '''遍历整个链表''' cur = self._head while cur != None: print(cur.elem, end="") cur = cur.next print("") def add(self, item): '''链表头部添加元素,头插法''' node = Node(item) node.next = self._head self._head = node node.next.prev = node def append(self, item): '''链表尾部添加元素 尾插法''' node = Node(item) if self.is_empty(): self._head = node else: cur = self._head while cur.next != None: cur = cur.next cur.next = node node.prev = cur def insert(self, pos, item): '''指定位置添加元素 :param pos从0开始 ''' if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: cur = self._head count = 0 while count < pos: count += 1 cur = cur.next # 当循环退出后,pre指向pos-1位置 node = Node(item) node.next = cur node.prev = cur.prev cur.prev.next = node cur.prev = node def remove(self, item): '''删除结点''' cur = self._head pre = None while cur != None: if cur.elem == item: # 先判断此结点是否是头结点 # 头结点 if cur == self._head: self._head = cur.next if cur.next: #判断链表是否只有一个结点 cur.next.prev = None else: cur.prev.next = cur.next if cur.next: cur.next.prev = cur.prev else: cur = cur.next def search(self, item): '''查找节点是否存在''' cur = self.__head while cur != None: if cur.elem == item: return True else: cur = cur.next return Falseif __name__ == "__main__" : dll = DoublelinkList() print(dll.is_empty()) print(dll.length()) dll.append(1) print(dll.is_empty()) print(dll.length()) dll.append(2) dll.add(8) dll.append(3) dll.append(4) dll.append(5) dll.append(6) # 8 1 2 3 4 5 6 dll.insert(-1, 9) # 9 8 123456 dll.travel() dll.insert(3, 100) # 9 8 1 100 23456 dll.travel()

单向循环链表

        单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。

操作

is_ empty()        判断链表是否为空
length()        返回链表的长度
travel()        遍历
add(item)        在头部添加一个结点
append(item)        在尾部添加一个结点
insert(pos, item)        在指定位置pos添加结点
remove(item)        删除一个结点
search(item)        查找节点是否存在
 

实现

# coding:utf-8class Node(object): '''结点''' def __init__(self, elem): self.elem = elem self.next = Noneclass SingleCyclelinkList(object): '''单向循环链表''' def __init__(self,node=None): self.__head = node if node: node.next = node def is_empty(self): """链表是否为空""" return self.__head == None def length(self): """链表长度""" if self.is_empty(): return 0 # cur游标, 用来移动遍历节点 cur = self.__head # count记录数量 count = 1 while cur.next != self.__head: count += 1 cur = cur.next return count def travel(self): '''遍历整个链表''' if self.is_empty(): return cur = self.__head while cur.next != self.__head: print(cur.elem, end="") cur = cur.next #推出循环,cur指向尾结点,但尾结点未打印 print(cur.elem) def add(self, item): """链表头部添加元素,头插法""" node = Node(item) if self.is_empty(): self.__head = node node.next = node else: cur = self.__head while cur.next != self.__head: cur = cur.next #推出循环,cur指向尾结点 node.next = self.__head self.__head = node cur.next = self.__head def append(self, item): """链表尾部添加元素 尾插法""" node = Node(item) if self.is_empty(): self.__head = node node.next = self.__head else: cur = self.__head while cur.next != self.__head: cur = cur.next node.next = self.__head cur.next = node def insert(self, pos, item): '''指定位置添加元素 :param pos从0开始 ''' if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: pre = self.__head count = 0 while count < (pos - 1): count += 1 pre = pre.next # 当循环退出后,pre指向pos-1位置 node = Node(item) node.next = pre.next pre.next = node def remove(self, item): '''删除结点''' if self.is_empty(): return cur = self.__head pre = None while cur.next != self.__head: if cur.elem == item: # 先判断此结点是否是头节结点 if cur == self.__head: #头结点情况 删头结点 找尾结点 rear = self.__head while rear.next != self.__head: rear = rear.next self.__head = cur.next rear.next = self.__head else: #中间结点 pre.next = cur.next return else: pre = cur cur = cur.next #推出循环,cur指向尾结点 if cur.elem == item: #游标所指元素是否是所要找的元素 if cur == self.__head: #链表只有一个结点 self.__head = None else: pre.next = cur.next #等于pre.next == self.__head def search(self, item): '''查找节点是否存在''' if self.is_empty(): return False cur = self.__head while cur.next != self.__head: if cur.elem == item: return True else: cur = cur.next #推出循环,cur指向尾结点 if cur.elem == item: return True return Falseif __name__ == "__main__" : ll = SingleCyclelinkList() print(ll.is_empty()) print(ll.length()) ll.append(1) print(ll.is_empty()) print(ll.length()) ll.append(2) ll.travel() ll.add(8) ll.append(3) ll.travel() ll.append(4) ll.append(5) ll.append(6) # 8 1 2 3 4 5 6 ll.insert(-1, 9) # 9 8 123456 ll.travel() ll.insert(3, 100) # 9 8 1 100 23456 ll.travel() ll.remove(9) ll.travel() ll.remove(100) ll.travel()

        栈(stack) ,有些地方称为堆栈是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一-端(称为栈顶端指标,英语: top) 进行加入数据(英语: push) 和输出数据(英语: pop)的运算。没有了位置概念,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素,确定了一种默认的访问顺序。由于栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。

操作

Stack()        创建一个新的空栈
push(item)        添加一个新的元素item到栈顶
pop()        弹出栈顶元素
peek()        返回栈顶元素
is_ empty()        判断栈是否为空
size()        返回栈的元素个数

实现

# coding: utf-8class Stack(object): """栈""" def __init__(self): self.__list = [] def push(self, item): """添加一个新的元素item到栈顶""" self.__list.append(item) def pop(self): """弹出栈顶元素""" return self.__list.pop() def peek(self): """返回栈顶元素""" if self.__list: return self.__list[-1] else: return None def is_empty(self): """判断栈是否为空""" return self.__list == [] # return not self.__list def size(self): """返回栈的元素个数""" return len(self.__list)if __name__ == "__main__": s = Stack() s.push(1) s.push(2) s.push(3) s.push(4) print(s.pop()) print(s.pop()) print(s.pop()) print(s.pop())

队列

队列(queue) 是只允许在一端进行插入操作, 而在另-一端进行删除操作的线性表。
        队列是一种先进先出的(First In First Out)的线性表,简称FIFO。 允许插入的一端为队尾,允许删除的一端为队头。队列不允许在中间部位进行操作!假设队列是q= (a1, a2, ...、an) ,那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,总是在队列最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然排在队伍最后。

操作

Queue()        创建一个空的队列
enqueue(item)         往队列中添加一个item元素
dequeue()        从队列头部删除-个元素
is_ empty()         判断-个队列是否为空
size()        返回队列的大小

 实现

# coding: utf-8class Queue(object): """队列""" def __init__(self): self.__list = [] def enqueue(self, item): """往队列中添加一个item元素""" self.__list.append(item) def dequeue(self): """从队列头部删除一个元素""" return self.__list.pop(0) def is_empty(self): """判断一个队列是否为空""" return self.__list == [] def size(self): """返回队列的大小""" return len(self.__list)if __name__ == "__main__": s = Queue() s.enqueue(1) s.enqueue(2) s.enqueue(3) s.enqueue(4) print(s.dequeue()) print(s.dequeue()) print(s.dequeue()) print(s.dequeue())

双端队列

双端队列(deque, 全名double-ended queue),是一种具有队列和栈的性质的数据结构。
        双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。

操作

Deque()       创建一个空的双端队列
add_ front(item)         从队头加入- -个item元素
add_ rear(item)         从队尾加入-个item元素
remove_ front()         从队头删除一个item元素
remove_ rear()       从队尾删除一个item元素
is_ empty()       判断双端队列是否为空
size()        返回队列的大小
 

实现

# coding: utf-8class Deque(object): """双端队列""" def __init__(self): self.__list = [] def add_front(self, item): """往队列头中添加一个item元素""" self.__list.insert(0, item) def add_rear(self, item): """往队列尾部添加一个item元素""" self.__list.append(item) def pop_front(self): """从队列头部删除一个元素""" return self.__list.pop(0) def pop_rear(self): """从队列尾部删除一个元素""" return self.__list.pop() def is_empty(self): """判断一个队列是否为空""" return self.__list == [] def size(self): """返回队列的大小""" return len(self.__list)if __name__ == "__main__": s = Deque() s.add_rear(1) s.add_rear(2) s.add_front(3) s.add_front(4) s.add_front(5) s.add_front(6) print(s.pop_rear()) print(s.pop_rear()) print(s.pop_front()) print(s.pop_rear()) print(s.pop_front()) print(s.pop_front())

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。