c语言链表实现双端队列,双向循环链表(实现双端队列和栈)

# -*- coding: utf-8 -*-

"""双向循环链表"""

class Node(object):

def __init__(self, item=None, prev=None, next=None):

self.item, self.prev, self.next = item, prev, next

class CirculaDoubleLinkList(object):

def __init__(self, maxsize=None):

node = Node()

node.next, node.prev = node, node

self.root = node

self.maxsize = maxsize

self.length = 0

def __len__(self):

return self.length

def tailnode(self):

return self.root.prev

def headnode(self):

return self.root.next

def append(self, item):

if self.maxsize and self.length >= self.maxsize:

raise Exception("Full")

node = Node(item)

tail_node = self.tailnode()

tail_node.next = node

node.prev = tail_node

node.next = self.root

self.root.prev = node

self.length += 1

def appendleft(self, item):

if self.maxsize and self.length >= self.maxsize:

raise Exception("Full")

node = Node(item)

if self.root.next is self.root: # empty

self.root.next = node

node.prev = self.root

node.next = self.root

self.root.prev = node

else:

headnode = self.headnode()

node.prev = self.root

self.root.next = node

node.next = headnode

headnode.prev = node

self.length += 1

def iter_node(self):

if self.root.next is self.root:

raise Exception("Lins in empty")

curnode = self.root.next

while curnode.next is not self.root:

yield curnode

curnode = curnode.next

yield curnode

def iter_node_reverse(self): # 反向遍历

if self.root.next is self.root:

raise Exception("List is empty")

curnode = self.tailnode()

while curnode.prev is not self.root:

yield curnode

curnode = curnode.prev

yield curnode

def __iter__(self):

for node in self.iter_node():

yield node.item

def remove(self, item): # 删除成功返回1 否则返回-1

prevnode = self.root

for node in self.iter_node():

if node.item == item:

prevnode.next = node.next

node.next.prev = node.prev

del node

self.length -= 1

return 1

else:

prevnode = prevnode.next

return -1

def find(self, item): # 查找元素 找到返回元素下标记 否则返回-1

index = 0

for node in self.iter_node():

if node.item == item:

return index

index += 1

return -1

def pop(self):

if not self.root.next:

raise EmptyError("List is empty")

tail_node = self.tailnode()

tail_node.prev.next = tail_node.next

tail_node.next.prev = tail_node.prev

del tail_node

self.length -= 1

def popleft(self):

if self.root.next is None:

raise Exception("List is empty")

headnode = self.root.next

self.root.next = headnode.next

headnode.next.prev = self.root

del headnode

self.length -= 1

def clear(self):

for node in self.iter_node():

del node

self.length = 0

# 基本方法单测

# def test_list():

# ll = CirculaDoubleLinkList()

#

# ll.append(0)

# ll.append(1)

# ll.append(2)

# assert ll.length == 3

#

# assert [node.item for node in ll.iter_node()] == [0, 1, 2]

# assert [node.item for node in ll.iter_node_reverse()] == [2, 1, 0]

#

# ll.remove(0)

# assert ll.length == 2

# assert list(ll) == [1, 2]

#

# ll.appendleft(0)

# assert ll.length == 3

# assert list(ll) == [0, 1, 2]

#

# ret = ll.find(2)

# assert ret == 2

#

# ll.popleft()

# ret1 = ll.find(0)

# assert ret1 == -1

#

# ll.clear()

# assert ll.length == 0

######################################################

# 定义异常类

######################################################

class FullError(Exception):

pass

class EmptyError(Exception):

pass

######################################################

# 双向循环链表实现双端队列

######################################################

class DoubleQueue(CirculaDoubleLinkList):

def append(self, value):

"""尾端增加元素"""

if len(self) >= self.maxsize:

raise FullError("queue full")

super().append(value)

def appendleft(self, value):

"""头部增加元素、"""

if len(self) >= self.maxsize:

raise FullError("queue full")

super(DoubleQueue, self).appendleft(value)

def pop(self):

if not len(self):

raise EmptyError("queue empty")

tail_node = self.tailnode()

value = tail_node.item

super(DoubleQueue, self).pop()

return value

def popleft(self):

if not len(self):

raise EmptyError("queue empty")

head_node = self.headnode()

value = head_node.item

super().popleft()

return value

def iter_value(self):

return self.iter_node()

# 单测

# def test_double_queue():

# maxsize = 5

# dq = DoubleQueue(maxsize)

# for i in range(maxsize):

# dq.append(i)

#

# assert len(dq) == 5

#

# import pytest

# with pytest.raises(FullError) as full_err:

# dq.append(5)

# assert "full" in str(full_err.value)

#

# with pytest.raises(FullError) as full_err:

# dq.appendleft(6)

# assert "full" in str(full_err.value)

#

# dq.pop()

#

# values = list()

# for node in dq.iter_value():

# values.append(node.item)

# assert values == [0, 1, 2, 3]

#

# dq.popleft()

# values = list()

# for node in dq.iter_value():

# values.append(node.item)

# assert values == [1, 2, 3]

# assert dq.pop() == 3

# assert dq.popleft() == 1

# dq.pop()

#

# with pytest.raises(EmptyError) as empty_err_info:

# dq.pop()

# assert "empty" in str(empty_err_info.value)

############################################################

# 循环双向链表实现 栈 Stack

############################################################

class Stack(DoubleQueue):

def push(self, value):

self.append(value)

def pop(self):

return super().pop()

def __len__(self):

return super(Stack, self).__len__()

def print_stack(self):

stack_values = list()

if self.length:

for node in self.iter_node():

stack_values.append(node.item)

return stack_values

# 循环双向链表实现栈 单测

# def test_stack():

# maxsize = 5

# stack = Stack(maxsize)

# for i in range(maxsize):

# stack.push(i)

#

# values = stack.print_stack()

# assert values == [0, 1, 2, 3, 4]

#

# assert len(stack) == 5

#

# import pytest

# with pytest.raises(FullError) as full_err:

# stack.push(8)

# assert "full" in str(full_err.value)

#

# assert stack.pop() == 4

# assert stack.print_stack() == [0, 1, 2, 3]

#

# for _ in range(stack.length):

# stack.pop()

# assert stack.print_stack() == []

#

# with pytest.raises(EmptyError) as empty_err:

# stack.pop()

# assert "empty" in str(empty_err.value)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值