数据结构与算法Day4

双向链表

在单链表的基础上,增加了一个链接,指向前一个节点(prev以及next两个链接)当当前节点为头节点时,prev指向空置,而next指向下一个节点。

双向链表的操作

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

在python中实现

class Node(object):

    def __init__(self,item):
    
        self.elem = item #元素
        self.next = None #下一个节点的指向
        self.prev = None #上一个节点的指向
class DoubleLinkList(object):

    def __init__(self,node=None):
        self.__head = node
    def is_empty(self):
        return(self.__head == 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
            
    def add(self,item):
    
        '''头部添加节点'''
        node = Node(item)
        node.next = self.__head #将新节点的下一个节点指向旧的头节点
        self.__head = node #将头结点更新为新节点
        node.next.prev = node #将下一个节点的prev指向新节点
        '''
        self.__head.prev = node
        self.__head = 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 #更新原链表next指向新节点
            node.prev = cur #更新新节点的prev指向
    def insert(self,pos,item):
     
		''' :param pos: 从0开始
		   :param item:
		   :return:'''
		        if pos < 0:
		            self.add(item) #同单链表一样
		        elif pos > (self.length()-1): #如果插入位置是最后一个 和在尾部添加相同
		            self.append(item)
		        else: #正常情况下 不断地走 走到pos指向位置的前一个位置停下 跳出循环
		            cur = self.__head 
		            count = 0
		            while count < (pos-1):
		                cur = cur.next
		                count += 1
		            #循环退出后 pre指向pos-1的位置
		            node = Node(item)
		            node.next = cur # 新节点下一节点指向pos位置上的节点
		            node.prev = cur.prev #新节点的前一个节点指向pos位置的前一个节点
		            cur.prev.next = node #更新cur.prev.next指向新节点
		            cur.prev = node #更新cur.prev指向新节点
		            '''
		            node.next = cur
		            node.prev = cur.prev
		            cur.prev = node
		            node.prev.next = node
		            与上四句话一样效果
		            '''
    def remove(self,item):
        cur = self.__head
        while cur != None: 
            if cur.elem == item: 
		  #先判断当前节点是否为头节点
		   #如果是头节点
	             if cur == self.__head:
	                 self.__head = cur.next #头节点直接指向下一个节点
	                 if cur.next != None: #不满足该条件证明只有一个节点 cur.next = None
	                     #判断链表是否只有一个节点 有下一个节点才有cur.next
	                     cur.next.prev = None #现在指针.next.prev指针指向空
             else:
              #打断cur前后的指向 将cur前一个节点next的指向 cur后一个节点
                 cur.prev.next = cur.next
                  #判断节点是否在尾部 不是尾部才有cur.next 尾部cur.next=None
                 if cur.next != None:
                     cur.next.prev = cur.prev
             break #一定退出!!!
         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 False

单向循环链表

在单链表的基础上,将单链表尾部节点的指向头节点,形成一个循环
常见操作函数

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

在Python中的操作:

class Node(object):

    def __init__(self,elem):
        self.elem = elem
        self.next = None

class 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):
	        # cur 游标 用来移动遍历节点
	        if self.is_empty():
	            return 0
	        cur = self.__head
	        # count 计数
	        count = 1 # 从1开始计数 因为从0开始计数会少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,end=' ')
	    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 # 将新节点插在头节点前 也就是新节点.next指向头节点
	            self.__head = node #定义新的头节点
	            cur.next = self.__head 尾节点指向头节点
	    def append(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.next = node #插入新节点 旧链表尾部节点.next指向新节点
	            node.next = self.__head #新节点.next指向头节点
	    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):
	                pre = pre.next
	                count += 1
	            #循环退出后 pre指向pos-1的位置
	            node = Node(item)
	            node.next = pre.next
	            pre.next = node
	    def remove(self,item):
	        #pre和cur 两个游标差一个位置
	        pre = None
	        cur = self.__head
	        if self.is_empty():
	            return
	        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 #打断原来链表头节点的指向 指向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):
	        cur = self.__head
	        while cur != self.__head:
	            if cur.elem == item:
	                return True #找到则返回
	            else:#没找到继续遍历
	                cur = cur.next
	        if cur.elem == item: #补充尾部节点的情况
	            return True
	        return False

栈又称为堆栈,是一种容器,用来存储线性数据,按照先进后出的规则运行。
在Python中的操作

class Stack(object):

    def __init__(self):
        self.__list = [] #初始化空列表
    def push(self,item):
        '''添加要给新的元素item'''
        self.__list.append(item)
        # self.__list.insert(0,item) 头部时间复杂度O(n) 尾部时间复杂度为O(1)
    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 == []
    def size(self):
        return len(self.__list)

队列

队列是允许在一段进行插入操作 而在另一端进行删除操作的线性表
按照先进先出的规律进行运行
在Python中的操作

class Queue(object):

    '''Queue() 创建一个空的队列
    enqueue(item) 往队列中添加一个item元素
    dequeue() 从队列头部删除一个元素
    is_empty() 判断一个队列是否为空
    size() 返回队列的大小'''
	    def __init__(self):#初始化空列表
	        self.__list = []
	    def enqueue(self,item):
	        self.__list.append(item)
	        #self.__list.insert(0,item) 对应不一样的dequue操作 
	    def dequeue(self):
	        '''从头部删除一个元素并返回'''
	        return self.__list.pop(0)
	    def is_empty(self):
	        return self.__list ==[]
	    def size(self):
	        return len(self.__list)

双端队列

可以选择从头或者尾 两端进行数据操作
在Python中的操作

class Deque(object):

    '''双端队列
    Deque() 创建一个空的双端队列
    add_front(item) 从队头加入一个item元素
    add_rear(item) 从队尾加入一个item元素
    remove_front() 从队头删除一个item元素
    remove_rear() 从队尾删除一个item元素
    is_empty() 判断双端队列是否为空
    size() 返回队列的大小'''
	
	    def __init__(self):
	        self.__list = []
	
	    def add_front(self, item):
	        '''从头部添加数据'''
	        self.__list.insert(0,item)
	    def add_rear(self, 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)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值