天天看點

python資料結構Python與資料結構二、連結清單

Python與資料結構

一、順序表

python資料結構Python與資料結構二、連結清單
  • 存儲位置 L O C ( a i + 1 ) LOC(a_{i+1}) LOC(ai+1​)和第i個資料元素的存儲位置為 L O C ( a i ) LOC(a_i) LOC(ai​)之間滿足下列關系

    L O C ( a a + 1 ) = L O C ( a i ) + l LOC(a_{a+1}) = LOC(a_i)+l LOC(aa+1​)=LOC(ai​)+l

  • 線性表的第 i i i個資料元素 a i a_i ai​的存儲位置為

L O C ( a i ) = L O C ( a 1 ) + ( i − 1 ) ∗ l LOC(a_i) = LOC(a_1)+(i-1)*l LOC(ai​)=LOC(a1​)+(i−1)∗l

python資料結構Python與資料結構二、連結清單
  • 尾端加入元素,時間複雜度為O(1)
  • 非保序的加入元素(不常見),O(1)
  • 保序的元素加入,時間複雜度為O(n)
python資料結構Python與資料結構二、連結清單
python資料結構Python與資料結構二、連結清單
  • 順序表元素外置,存儲表的位址,然後再找到存儲的資料
  • python中順序表 是用操作append,pop等
  • python資料結構Python與資料結構二、連結清單
    python資料結構Python與資料結構二、連結清單

二、連結清單

python資料結構Python與資料結構二、連結清單

2.1 單向連結清單

python資料結構Python與資料結構二、連結清單

産生資料結構,定義為類

python資料結構Python與資料結構二、連結清單
  • 定義結點類
class Node(object):
    """
    建立結點類
    """
    def __init__(self,elem):
        self.elem = elem
        self.next = None
        # 初始為空值
           
  • 定義單連結清單類
class SingleLinkList(object):
    """單連結清單"""
    def __init__(self,node=None):
        """
        指向頭結點,預設為空值
        :param node:
        """
        self.__head = node
    def is_empty(self):
        """連結清單是否為空"""
        return self.__head == None
    def length(self):
        """連結清單長度"""
        # cur 指針用來移動周遊結點
        cur = self.__head
        # count 記錄數量
        count = 0 # count初始化為0
        while cur != None:
            count += 1
            cur = cur.next
            # count = 1
            # cur.next != None
        return count

    def travel(self):
        """周遊整個連結清單"""
        cur = self.__head
        while cur != None:
            print(cur.elem,end = " ")
            cur = cur.next
        print("\t")

    def add(self,item):
        """連結清單頭部添加元素,頭插法"""
        node = Node(item)
        node.next = self.__head
        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

    def insert(self,pos,item):
        """指定位置添加元素
        :param pos from 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):
        """删除節點"""
        cur  = self.__head
        pre = None
        while cur != None:
            if cur.elem == item:
                # 先判斷此結點是否為頭結點
                # 頭結點:
                if cur == self.__head:
                    self.__head = cur.next
                    break
                else:
                    pre.next = cur.next
                break
            else:
                pre = cur
                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
           
python資料結構Python與資料結構二、連結清單
class Node(object):
    """
    建立結點類
    """
    def __init__(self,elem):
        self.elem = elem
        self.next = None

class SingleLinkList(object):
    """單連結清單"""
    def __init__(self,node=None):
        """
        指向頭結點,預設為空值
        :param node:
        """
        self.__head = node
    def is_empty(self):
        """連結清單是否為空"""
        return self.__head == None
    def length(self):
        """連結清單長度"""
        # cur 指針用來移動周遊結點
        cur = self.__head
        # count 記錄數量
        count = 0 # count初始化為0
        while cur != None:
            count += 1
            cur = cur.next
            # count = 1
            # cur.next != None
        return count

    def travel(self):
        """周遊整個連結清單"""
        cur = self.__head
        while cur != None:
            print(cur.elem,end = " ")
            cur = cur.next
        print("\t")

    def add(self,item):
        """連結清單頭部添加元素,頭插法"""
        node = Node(item)
        node.next = self.__head
        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

    def insert(self,pos,item):
        """指定位置添加元素
        :param pos from 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):
        """删除節點"""
        cur  = self.__head
        pre = None
        while cur != None:
            if cur.elem == item:
                # 先判斷此結點是否為頭結點
                # 頭結點:
                if cur == self.__head:
                    self.__head = cur.next
                    break
                else:
                    pre.next = cur.next
                break
            else:
                pre = cur
                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



# node = Node(100)

if __name__ == "__main__":
    ll = SingleLinkList()
    print(ll.is_empty())
    print(ll.length())

    ll.append(10)
    print(ll.is_empty())
    print(ll.length())

    ll.append(2)
    ll.append(3)
    ll.append(4)
    ll.append(5)
    ll.append(6)
    ll.add(100)
    ll.insert(-1,9)
    ll.insert(2,1000)
    ll.insert(10,10000)
    ll.travel()
    ll.remove(100)
    ll.travel()
    ll.remove(10000)
    ll.travel()
           
python資料結構Python與資料結構二、連結清單
python資料結構Python與資料結構二、連結清單

2.2 雙向連結清單

python資料結構Python與資料結構二、連結清單
python資料結構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):
        """
        指向頭結點,預設為空值
        :param node:
        """
        self.__head = node
    def is_empty(self):
        """連結清單是否為空"""
        return self.__head is None
    def length(self):
        """連結清單長度"""
        # cur 指針用來移動周遊結點
        cur = self.__head
        # count 記錄數量
        count = 0 # count初始化為0
        while cur != None:
            count += 1
            cur = cur.next
            # count = 1
            # cur.next != None
        return count

    def travel(self):
        """周遊整個連結清單"""
        cur = self.__head
        while cur != None:
            print(cur.elem,end = " ")
            cur = cur.next
        print("\t")
    # 以上和singlelinklist操作一樣

    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 from 0
        """
        if pos<=0:
            self.add(item)
        elif pos>(self.length()-1):
            self.append(item)
        else:
            cur = self.__head
            count = 0
            while count< pos:
                cur = cur.next
                count += 1
            # 當循環結束後,cur指向pos位置
            node = Node(item)
            node.next = cur
            node.prev = cur.prev
            cur.prev.next = node
            cur.prev = 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:
                        # 判斷連結清單是否隻有一個結點
                        cur.next.prev = None
                    cur.next.prev = None
                else:
                    cur.prev.next = cur.next
                    if cur.next:
                        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

if __name__ == "__main__":
    ll = DoubleLinkList()

    print(ll.is_empty())
    print(ll.length())

    ll.append(10)
    print(ll.is_empty())
    print(ll.length())

    ll.append(2)
    ll.append(3)
    ll.append(4)
    ll.append(5)
    ll.append(6)
    ll.add(100)
    ll.insert(-1,9)
    ll.insert(2,1000)
    ll.insert(10,10000)
    ll.travel()
    ll.remove(100)
    ll.travel()
    ll.remove(10000)
    ll.travel()
           
python資料結構Python與資料結構二、連結清單

2.3 單向循環連結清單

# -*- coding:utf-8 -*-
# Author : XuQiao

class Node(object):
    """
    建立結點類
    """
    def __init__(self,elem):
        self.elem = elem
        self.next = None

class SingleCycleLinkList(object):
    """單向循環連結清單"""
    def __init__(self,node=None):
        """
        指向頭結點,預設為空值
        :param node:
        """
        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)
            cur = cur.next
        # 退出循環,cur指向尾結點,但尾結點的元素未列印
        print(cur.elem,end=" ")
        print("\t")


    def add(self,item):
        """連結清單頭部添加元素,頭插法"""
        node = Node(item)
        if self.is_empty():
            self.__head = node
            self.__head.next = self.__head
            return
        cur = self.__head
        while cur.next != self.__head:
            cur = cur.next
        node.next = self.__head
        self.__head = node
        cur.next = self.__head

    def append(self,item):
        """連結清單尾部添加元素,尾插法"""
        node = Node(item)
        cur = self.__head
        if self.is_empty():
            self.__head = node
            self.__head.next = self.__head
            return
        while cur.next != self.__head:
            cur = cur.next
        node.next = cur.next
        cur.next = node

    def insert(self,pos,item):
        """指定位置添加元素
        :param pos from 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):
        """删除節點"""
        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

                    # self.__head = cur.next
                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

    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
        if cur.elem == item:
            return True
        return False



# node = Node(100)

if __name__ == "__main__":
    ll = SingleCycleLinkList()
    print(ll.is_empty())
    print(ll.length())

    ll.append(10)
    print(ll.is_empty())
    print(ll.length())

    ll.append(2)
    ll.append(3)
    ll.append(4)
    ll.append(5)
    ll.append(6)
    ll.add(100)
    ll.insert(-1,9)
    ll.insert(2,1000)
    ll.insert(10,10000)
    ll.travel()
    ll.remove(100)
    ll.travel()
    ll.remove(10000)
    ll.travel()