python的单向列表和双向列表(用程序来实现)

1、链表(Linked list)

链表是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。

在这里插入图片描述
链表是通过每个结点的指针与将线性表的n个节点按期逻辑次序连接在一起的。
在这里插入图片描述

2.单向链表

单向链表每一个节点包含两个域,一个信息域(元素域)和一个连接域。这个连接指向链表中的下一个节点,而最后一个节点的连接域则指向一个空值
在这里插入图片描述
如上图:

  • 表元素域elem用来存放具体的数据
  • 连接域next用来存放下一个节点的位置(python中的标识)
  • 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。

节点用程序实现:

class SingleNode(object):
    #单向链表的节点
      def __init__(self,item):
      #item 存放数据元素
      self.item=item
      #next是下一个节点的标识
      self.next=None

单向链表的操作

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

用来程序实现:

class SingleLinkList(object):
    #单向列表
    def __init__(self):
        self.head=None

判断链表是否为空

def is_empty(self):
        return self.head==None

链表长度

 def length(self):
        cur=self.head#ucr初始时指向头节点
        count=0
        while cur!=None:
            count+=1
            cur=cur.next#将cur后移一个节点
        return count

遍历整个链表


  def travel(self):
        cur=self.head
        while cur !=None:
            print(cur.item)
            cur=cur.next
        print('')

头部添加元素

在这里插入图片描述

  def add(self,item):
        #先创建一个保存item值得节点
        node=SingleNode(item)
        #将新节点的连接next指向头节点,即head指向的位置
        node.next=self.head
        #将链表的头head指向新节点
        self.head=node

尾部添加元素:

def  append(self,item):
        node=SingleNode(item)
        #先判断链表是否为空,若是空链表,则将head指向新节点
        if self.is_empty():
            self.head=node
        #若不为空,则找到尾部,将找到尾部,将尾节点的next指向新节点
        else:
            cur=self.head
            while cur.next!=None:
                cur=cur.next
            cur.next=node

指定位置添加元素
在这里插入图片描述

def insert(self,pos,item):
        #若指定位置pos为第一个元素之前,则执行头部插入
         if pos <=0:
             self.add(item)
         #若指定位置超过链表尾部,则执行尾部插入
         elif pos>(self.length()-1):
             self.append(item)
         #找到指定的位置
         else:
             node=SingleNode(item)
             count=0
             #pre用来指定位置pos的前一个位置pos-1,初始从头及诶单开始移动到指定位置
             pre=self.head
             while count<(pos-1):
                 count+=1
                 pre=pre.next
             #先将新节点node的next指向插入位置的节点
                 node.next=pre.next
             #将插入的位置前的一个节点的next指向新节点
                 pre.next=node

删除节点
在这里插入图片描述

 def remove(self,item):
        cur=self.head
        pre=None
        while cur!=None:
            #找到了指定元素
            if cur.item==item:
               #如果第一个就是删除的节点
               if not pre:
                   self.head=cur.next
               else:
                   #将删除位置前一个节点的next指向删除位置的后一个节点
                    pre.next=cur.next
                    break
            else:
                #继续按链表后移节点
                 pre=cur
                 cur=cur.next

查找节点是否存在

    def search(self,item):#查找节点是否存在,并返回True或者False
        cur=self.head
        while cur!=None:
            if cur.item==item:
                return True
            cur=cur.next
        return False

测试

if __name__ == '__main__':
    ll=SingleLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.insert(2,4)
    print('length:',ll.length())
    ll.travel()
    print(ll.search(3))
    print(ll.search(5))
    ll.remove(1)
    print('length:',ll.length())
    ll.travel()

双向链表

定义:每个节点有两个链表:一个指向前一个节点,当此节点为第一个节点时,指向空值,而另一个指向下一个节点,当次节点为最后一个节点时,当此节点为最后的一个节点,指向空值。
在这里插入图片描述
也就是说,构成链表的每个节点设立两个指正域,一个指向其直接前驱指针域prior,一个指向其直接后继的指针域next。这样形成的链表有两个方向不同的链。

双向链表的操作

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

用程序实现

class Node(object):
    """双向链表节点"""
    def __init__(self, item):
        self.item = item
        self.next = None
        self.prev = None


class DLinkList(object):
    """双向链表"""
    def __init__(self):
        self._head = None



    def is_empty(self):
        """判断链表是否为空"""
        return self._head == None



    def length(self):
        """返回链表的长度"""
        cur = self._head
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count



    def travel(self):
        """遍历链表"""
        cur = self._head
        while cur != None:
            print cur.item,
            cur = cur.next
        print ""



    def add(self, item):
        """头部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
         self._head = node
        else:
            # 将node的next指向_head的头节点
            node.next = self._head
            # 将_head的头节点的prev指向node
            self._head.prev = node
            # 将_head 指向node
            self._head = node



    def append(self, item):
        """尾部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 移动到链表尾部
            cur = self._head
            while cur.next != None:
                cur = cur.next
            # 将尾节点cur的next指向node
            cur.next = node
            # 将node的prev指向cur
            node.prev = cur



def insert(self, pos, item):
        """在指定位置添加节点"""
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 移动到指定位置的前一个位置
            while count < (pos-1):
                count += 1
                cur = cur.next
            # 将node的prev指向cur
            node.prev = cur
            # 将node的next指向cur的下一个节点
            node.next = cur.next
            # 将cur的下一个节点的prev指向node
            cur.next.prev = node
            # 将cur的next指向node
            cur.next = node



    def search(self, item):
        """查找元素是否存在"""
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False    
     



    def remove(self, item):
        """删除元素"""
        if self.is_empty():
            return
        else:
            cur = self._head
            if cur.item == item:
                # 如果首节点的元素即是要删除的元素
                if cur.next == None:
                    # 如果链表只有这一个节点
                    self._head = None
                else:
                    # 将第二个节点的prev设置为None
                    cur.next.prev = None
                    # 将_head指向第二个节点
                    self._head = cur.next
                return
            while cur != None:
                if cur.item == item:
                    # 将cur的前一个节点的next指向cur的后一个节点
                    cur.prev.next = cur.next
                    # 将cur的后一个节点的prev指向cur的前一个节点
                    cur.next.prev = cur.prev
                    break
                cur = cur.next

测试程序的正确性

if __name__ == "__main__":
    ll = DLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.insert(2, 4)
    ll.insert(4, 5)
    ll.insert(0, 6)
    print "length:",ll.length()
    ll.travel()
    print ll.search(3)
    print ll.search(4)
    ll.remove(1)
    print "length:",ll.length()
    ll.travel()

猜你喜欢

转载自blog.csdn.net/xmxt668/article/details/88598505