01.线性表

顺序表

python中的list和tuple就采用了顺序表的实现技术

tuple是不变的表,因此不支持改变其内部状态的任何操作

list是一种元素个数可变的线性表,可以加入和删除元素,在各种操作中维持已有元素的顺序

list对象无法设置容量的操作

 

if __name__ == '__main__':
    lt = list([1, 3, 2])
    print(len(lt))  # 3
    print(lt)  # [1, 3, 2]
    # 元素顺序倒置
    lt.reverse()
    print(lt)  # [2, 3, 1]
    # 排序
    lt.sort()
    print(lt)  # [1, 2, 3]
    # 清除表中所有元素
    lt.clear()
    print(len(lt))  # 0

 

单链表:

单链表头部添加元素:

 

 

class LNode:
    """表节点"""

    # next_防止与标准函数next重名
    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next = next_


class LinkedListUnderflow(ValueError):
    pass


class LList:
    """单链表"""

    def __init__(self):
        self._head = None

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

    def __len__(self):
        """链表长度"""
        count = 0
        p = self._head
        while p:
            count += 1
            p = p.next
        return count

    def prepend(self, elem):
        """表头插入数据"""
        # node = LNode(elem)
        # node.next = self._head
        # self._head = node
        # 合并为一句
        self._head = LNode(elem, self._head)

    def pop(self):
        """删除头一个元素"""
        if self._head is None:  # 无结点,抛出异常
            raise LinkedListUnderflow("in pop")
        e = self._head.elem
        self._head = self._head.next
        return e

    def append(self, elem):
        """尾部添加元素"""
        if self._head is None:
            self._head = LNode(elem)
            return
        p = self._head
        while p.next is not None:
            p = p.next
        p.next = LNode(elem)

    def printall(self):
        p = self._head
        while p:
            print(p.elem, end='')
            if p.next:
                print(', ', end='')
            p = p.next
        print('')

    def for_each(self, proc):
        """遍历函数,proc的参数应该是可以作用于表元素的操作函数,如:print"""
        p = self._head
        while p:
            proc(p.elem)
            p = p.next

    def elements(self):
        """迭代器"""
        p = self._head
        while p:
            yield p.elem
            p = p.next

    def find(self, pred):
        """返回符合条件的第一个"""
        p = self._head
        while p is not None:
            if pred(p.elem):
                return p.elem
            p = p.next

    def filter(self, pred):
        """筛选生成器"""
        p = self._head
        while p is not None:
            if pred(p.elem):
                yield p.elem
            p = p.next

if __name__ == '__main__':
    llist1 = LNode(1)
    p = llist1
    for i in range(2, 11):
        p.next = LNode(i)
        p = p.next
    p = llist1
    # 可简写 while p:
    while p is not None:
        print(p.elem)
        p = p.next
    mlist1 = LList()
    for i in range(3):
        mlist1.prepend(i)
    for i in range(4, 7):
        mlist1.append(i)
    mlist1.printall()  # 2, 1, 0, 4, 5, 6
    mlist1.for_each(print)
    print("-------")
    for x in mlist1.elements():
        print(x, end=' ')  # 2 1 0 4 5 6
    print("-------")
    print(mlist1.find(lambda z: z > 3))  # 4
    print("-------")
    for x in mlist1.filter(lambda z: z > 3):
        print(x, end=' ')  # 4 5 6
    print("-------")
    print(len(mlist1))  # 6

 补充单链表的排序:

def sort(self):
        """从小到大排序 通过移动表中元素实现"""
        if self._head is None:
            return
        crt = self._head.next  # 待插入的点
        while crt:
            x = crt.elem
            p = self._head
            while p is not crt and p.elem <= x:
                p = p.next
            while p is not crt:
                y = p.elem
                p.elem = x
                x = y
                p = p.next
            crt.elem = x  # 回填最后一个元素
            crt = crt.next

    def sort2(self):
        """从小到大排序 通过调整结点之间的实现"""
        p = self._head
        if p is None or p.next is None:
            return
        rem = p.next  # 待插入的点
        p.next = None  # 第一个元素作为排序好的元素
        while rem:
            p = self._head  # 每次从排好的第一个开始比较
            q = None
            while p and p.elem <= rem.elem:  # 新插入的大遍历放排序好的最后
                q = p
                p = p.next
            if q is None:  # 新插入的最小,所有作为头
                self._head = rem
            else:
                q.next = rem
            q = rem
            rem = rem.next
            q.next = p

 

 带有尾节点引用的单链表:

头部添加元素:

 

 反转:

 

 

 

class LList2(LList):
    """带有尾节点引用的单链表"""

    def __init__(self):
        # 相当于LList.__init__()
        super(LList2, self).__init__()
        self._rear = None

    def prepend(self, elem):
        """表头插入数据"""
        if self._head is None:
            self._head = LNode(elem, self._head)
            self._rear = self._head
        else:
            self._head = LNode(elem, self._head)

    def append(self, elem):
        """尾部添加元素"""
        if self._head is None:
            self._head = LNode(elem, self._head)
            self._rear = self._head
        else:
            self._rear.next = LNode(elem)
            self._rear = self._rear.next

    def pop_last(self):
        """弹出末尾元素"""
        if self._head is None:
            raise LinkedListUnderflow("in pop_last")
        p = self._head
        # 只有一个元素
        # 表判断空用_head的值,所有删除最后一个结点使表变空时,不需要给_rear赋值None
        if p.next is None:
            e = p.elem
            self._head = None
            return e
        while p.next.next:
            p = p.next
        e = p.next.elem
        p.next = None
        self._rear = p
        return e
  def rev(self):
  """反转"""
  p = None
  if self._head:
  self._rear = self._head
  while self._head:
  q = self._head
  self._head = q.next
  q.next = p
  p = q
  self._head = p

if __name__ == '__main__': 
  mlist1
= LList2()
  mlist1.prepend(
1)
  mlist1.prepend(
2)

  for i in range(3, 5):
    mlist1.append(i)

  for i in mlist1.elements():
    print(i, end=' ') # 2 1 3 4
    print("---------")
    print(mlist1.pop_last()) # 4

 循环单链表:

class LNode:
    """表节点"""

    # next_防止与标准函数next重名
    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next = next_


class LinkedListUnderflow(ValueError):
    pass


class LCList:
    """循环单链表"""

    def __init__(self):
        self._rear = None

    def is_empty(self):
        return self._rear is None

    def prepend(self, elem):
        """首端插入"""
        p = LNode(elem)
        if self._rear is None:
            p.next = p
            self._rear = p
        else:
            p.next = self._rear.next
            self._rear.next = p

    def append(self, elem):
        """尾端插入"""
        self.prepend(elem)
        self._rear = self._rear.next

    def pop(self):
        """首端弹出"""
        if self._rear is None:
            raise LinkedListUnderflow("in pop of LCList")
        p = self._rear.next
        # 只有一个元素
        if self._rear is p:
            self._rear = None
        else:
            self._rear.next = p.next
        return p.elem

    def printall(self):
        """输出表元素"""
        if self.is_empty():
            return
        p = self._rear.next
        while 1:
            print(p.elem)
            if p is self._rear:
                break
            p = p.next


if __name__ == '__main__':
    mlclist1 = LCList()
    mlclist1.prepend(1)
    mlclist1.prepend(2)
    for i in range(3, 5):
        mlclist1.append(i)
    mlclist1.printall()
    # 2
    # 1
    # 3
    # 4
    print("---------")
    print(mlclist1.pop())  # 2

 

双链表:

class DLNode:
    """双链表节点"""

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


class LinkedListUnderflow(ValueError):
    pass


class DLLList:
    """双链表"""

    def __init__(self):
        self._head = None
        self._rear = None

    def is_empty(self):
        return self._head is None

    def prepend(self, elem):
        """首端插入"""
        p = DLNode(elem, None, self._head)
        if self._head is None:
            self._rear = p
        else:
            p.next.prev = p
        self._head = p

    def append(self, elem):
        """尾端插入"""
        p = DLNode(elem, self._rear, None)
        if self._head is None:
            self._head = p
        else:
            p.prev.next = p
        self._rear = p

    def pop(self):
        """首端弹出"""
        if self._head is None:
            raise LinkedListUnderflow("in pop of LCList")
        e = self._head.elem
        self._head = self._head.next
        if self._head:
            self._head.prev = None
        return e

    def pop_last(self):
        if self._head is None:
            raise LinkedListUnderflow("in pop_last of LCList")
        e = self._rear.elem
        self._rear = self._rear.prev
        if self._rear is None:
            self._head = None
        else:
            self._rear.next = None
        return e

    def printall(self):
        """输出表元素"""
        if self.is_empty():
            return
        p = self._head
        while 1:
            print(p.elem)
            if p is self._rear:
                break
            p = p.next


if __name__ == '__main__':
    mlclist1 = DLLList()
    mlclist1.prepend(1)
    mlclist1.prepend(2)
    for i in range(3, 5):
        mlclist1.append(i)
    mlclist1.printall()
    # 2
    # 1
    # 3
    # 4
    print("---------")
    print(mlclist1.pop())  # 2
    print(mlclist1.pop_last())  # 4

 

posted @ 2019-10-16 16:06  fly_bk  阅读(168)  评论(0编辑  收藏  举报