python数据结构(二):线性表

一,线性表简介

(一)定义

线性表是由若干个具有相同特性的数据元素组成的有限序列

  • 若该线性表中不包含任何元素,则称为空表, 此时其长度为零。
  • 若该线性表不为空, 则表中元素的个数为表长度。

(二)形式

{a[l],a[2],,a[i],,a[n]}

(三)逻辑结构

在这里插入图片描述
如果表中元素按某种顺序进行排列,则称这种类型的线性表为有序线性表,否则称其为无序线性表

(四)存储结构

采用顺序存储结构的顺序表,采用链式存储结构的链表。

顺序存储结构:用一块连续的存储空间存储数据元素,用元素的存储位置关系表示元素间的逻辑关系。

链式存储结构:用存储节点来存储数据元素以及元素关系。其中一个节点分为数据域和指针域,数据域存储数据元素,指针域存储逻辑上下一个元素的存储地址。

(五) 线性表的特性

  1. 线性表中的元素个数一定是有限的。
  2. 线性表中的所有元素具有相同的性质。
  3. 线性表中除表头元素以外, 其他所有元素都有唯一的(直接) 先驱元素。
  4. 线性表中除表尾元素以外, 其他所有元素都有唯一的(直接) 后继元素。

二,顺序表

(一)顺序表的概念

顺序表就是指采用顺序存储的方式来存储数据元素的线性表。
在这里插入图片描述

(二)顺序表的实现

基本操作:

序号方法功能
1__init__()初始化一个空顺序表
2CreateSequenceList(keys_list)方法创建非空顺序表
3GetElement(position)获取指定位置上的元素值
4FindPosition(key)查找指定元素的位置
5InsertElement(element, position)在指定位置插入元素
6DeleteElement(position)在指定位置删除元素
7TraverseElement()遍历所有元素
8CLearSequenceList()方法清空当前顺序表
9DestroySeqList()方法销毁顺序表
10ReverseList()方法逆序顺序表
"""
@Project :practice 
@File    :1——顺序表.py
@Author  :Dang Funlin
@Version :2.0
@Date    :2021/8/22 10:00
"""


class SequenceList(object):
    """
    类名:SequenceList
    功能:定义顺序表
    """

    def __init__(self):
        """1,初始化一个空顺序表。
        :param:无。
        :return:无。
        """
        self.SeqList = []

    def CreateSequenceList(self, keys_list):
        """2,创建非空顺序表。
        :param: 待插入的非空列表keys_list。
        :return: 创建非空顺序表成功,返回True。
        """
        if keys_list is not None:
            print("正在创建顺序表......")
            self.SeqList = [x for x in keys_list]
            print("创建后,顺序表为:", self.SeqList)
            return True
        else:
            print("创建顺序表失败!")
            return False

    def GetElement(self, position):
        """3,获取指定位置上的元素值
        :param: 待查找的位置position。
        :return: 获取成功,返回指定位置的元素值key。
        """
        if position not in range(1, len(self.SeqList) + 1):
            print("位置不合法!")
            return False
        else:
            print("正在获取元素......")
            key = self.SeqList[position - 1]
            print("该位置的元素为:", key)
            return key

    def FindPosition(self, key):
        """4,查找指定元素的位置(下表从0开始)
        :param: 待查找位置的元素值key。
        :return: 查找成功,返回元素所在的位置。
        """
        position = []
        if key in self.SeqList:
            position.append(self.SeqList.index(key) + 1)
            print("查找成功!", key, "在当前顺序表的第", position, "位")
            return position
        else:
            print("查找失败!当前顺序表中不存在值为", key, "的元素")
            return False

    def InsertElement(self, element, position):
        """5,在指定位置插入元素
        :param: 待插入的元素值element,待插入的位置position。
        :return: 插入元素成功,返回True。
        """
        if position not in range(0, len(self.SeqList) + 2):
            print("位置不合法!")
            return False
        else:
            print("正在插入元素......")
            self.SeqList.insert(int(position) - 1, element)
            print("插入元素后,顺序表为:", self.SeqList)
            return True

    def DeleteElement(self, position):
        """6,在指定位置删除元素
        :param: 待删除位置position。
        :return: 删除成功,返回被删除的元素值key。
        """
        if position not in range(0, len(self.SeqList) + 2):
            print("位置不合法!")
            return False
        else:
            print("正在删除元素", self.SeqList[int(position) - 1], "......")
            key = self.SeqList[int(position) - 1]
            self.SeqList.remove(self.SeqList[int(position) - 1])
            print("删除元素后,顺序表为:", self.SeqList)
            return key

    def TraverseElement(self):
        """7,遍历所有元素。
        :param: 无。
        :return: 成功遍历,返回True。
        """
        try:
            sqlen = len(self.SeqList)
        except:
            print("该顺序表已不存在!")
        else:
            print("即将遍历顺序表......")
            if sqlen > 0:
                for i in range(0, sqlen):
                    print("第", i + 1, "个元素的值为", self.SeqList[i])
                return True
            elif sqlen == 0:
                print("该顺序表为空!")
            else:
                print("该顺序表已不存在!")

    def CLearSequenceList(self):
        """8,清空当前顺序表
        :param: 无。
        :return: 无。
        """
        print("正在清空顺序表......")
        self.SeqList = []
        print("成功清空该顺序表!")
        return

    def DestroySeqList(self):
        """9,销毁顺序表。
        :param: 无。
        :return: 成功销毁,返回True。
        """
        try:
            del self.SeqList
        except:
            print("销毁该顺序表失败!")
            return False
        else:
            print("销毁该顺序表成功!")
            return True

    def ReverseList(self):
        """10,逆序顺序表。
        :param: 无。
        :return: 无。
        """
        i, j = 0, len(self.SeqList)-1
        while i < j:
            self.SeqList[i], self.SeqList[j] = self.SeqList[j], self.SeqList[i]
            i, j = i + 1, j - 1

if __name__ == '__main__':
    sq = SequenceList()
    keys = [1, 2, 3, 4, 5, 6]
    sq.CreateSequenceList(keys_list=keys)
    sq.TraverseElement()
    sq.InsertElement(7, 7)
    sq.InsertElement(8, 8)
    sq.ReverseList()
    sq.TraverseElement()
    sq.GetElement(7)
    sq.DeleteElement(7)
    sq.CLearSequenceList()
    sq.TraverseElement()
    print(sq.SeqList)
    # del sq  # 销毁当前顺序表, print(sq)将报错:name 'sq' is not defined
    sq.DestroySeqList()
    sq.TraverseElement()
    
>>>
正在创建顺序表......
创建后,顺序表为: [1, 2, 3, 4, 5, 6]
即将遍历顺序表......1 个元素的值为 12 个元素的值为 23 个元素的值为 34 个元素的值为 45 个元素的值为 56 个元素的值为 6
正在插入元素......
插入元素后,顺序表为: [1, 2, 3, 4, 5, 6, 7]
正在插入元素......
插入元素后,顺序表为: [1, 2, 3, 4, 5, 6, 7, 8]
即将遍历顺序表......1 个元素的值为 82 个元素的值为 73 个元素的值为 64 个元素的值为 55 个元素的值为 46 个元素的值为 37 个元素的值为 28 个元素的值为 1
正在获取元素......
该位置的元素为: 2
正在删除元素 2 ......
删除元素后,顺序表为: [8, 7, 6, 5, 4, 3, 1]
正在清空顺序表......
成功清空该顺序表!
即将遍历顺序表......
该顺序表为空!
[]
销毁该顺序表成功!
该顺序表已不存在!

(三)顺序表特点总结

1,随机访问

顺序表最大特点就是能随机访问

因为元素的逻辑顺序与物理顺序相同,所以假设存储第一个元素的起始地址为 Locate(a[0]) 并且每个元素占用 S 个存储空间,那么第 i+1 个元素与第 1 个元素之间的存储位置关系可以用 Locate(a[i])=Locate(a[0])+(i-1)*S来表示

  • 随机访问的时间复杂度是O(1)。

当进行顺序查找时:
最好情况:在表头找到,时间复杂度为O(1);
最坏情况:在表i尾找到,时间复杂度为O(n);
平均情况:在表中找到,查找 (n+1)/2 个元素,时间复杂度为O(n);

2,存储密度高

因为顺序表中的每个结点完全用于存储数据元素,所以顺序表的存储密度高。

3,需要移动元素

尽管用python实现的顺序表的插入与删除操作并没有显式地移动任何元素,但这里使用到的CPython在用C语言实现底层代码时确实实现了调整列表容量、确定插入/删除点、插入/删除元素等一系列操作。

(1)插入元素时

在这里插入图片描述

最好情况:在表尾插入(i=n+1),不移动元素,时间复杂度为O(1);
最坏情况:在表i头插入(i=1),移动 n 个元素,时间复杂度为O(n);
平均情况:在表中插入,移动 n/2 个元素,时间复杂度为O(n);

(2)删除元素时

最好情况:在表尾删除(i=n),不移动元素,时间复杂度为O(1);
最坏情况:在表i头删除(i=1),移动 n 个元素,时间复杂度为O(n);
平均情况:在表中删除,移动 (n-1)/2 个元素,时间复杂度为O(n);

三,链表

链表是指采用链式结构来存储数据元素的线性表。

(一)单链表

1,单链表的概念

链表结点只有一个指向后继结点的指针域且尾结点指针域为空的链表叫单链表。

在这里插入图片描述

2,单链表的实现

带头结点的单链表的基本操作:

序号方法功能
1Node.__init__(data)方法初始化单链表结点
2SingleLinkedList.__init__()方法初始化单链表头结点
3GetLength()方法获取单链表长度
4IsEmpty()方法判断链表是否为空
5TraverseElement()方法遍历单链表
6Create()方法尾插法创建单链表
7InsertElementInTail(key)方法尾插法插入元素
8InsertElementInHead(key)方法头插法插入元素
9InsertElementInSpecifiedPosition(key, position)方法在指定位置插入结点
10GetElement(position)方法获取指定位置结点的元素值
11SetElement(key, position)方法设置指定位置的元素值
12FindPosition(key)方法查找指定元素的位置
13DeleteElementInSpecifiedPosition(position)方法删除指定位置的结点
14DeleteElement(key)方法删除所有包含指定元素的结点
15ClearSingleLinkedList()方法清空当前单链表
16DestroySingleLinkedList()方法销毁当前单链表
17RverseSingleLinkedList()方法逆置当前单链表
"""
@Project :practice 
@File    :1——单链表.py
@Author  :Dang Funlin
@Version :2.0
@Date    :2021/8/30 10:02 
"""


class Node(object):
    """
    类名:Node。
    功能:定义单链表结点。
    """

    def __init__(self, data):
        """1,初始化单链表结点。
        :param: 链表结点的数据data。
        """
        self.data = data  # 数据域
        self.next = None  # 指针域


class SingleLinkedList(object):
    """
    类名:SingleLinkedList。
    功能:定义单链表。
    """

    def __init__(self):
        """2,初始化单链表头结点。
        :param: 无。
        :return: 无。
        """
        self.head = Node("这是头结点的数据")

    def GetLength(self):
        """3,获取单链表长度。
        :param: 无。
        :return: 当前单链表长度length。
        """
        currentNode = self.head
        length = 0
        while currentNode.next is not None:  # 从第一个元素结点开始计数
            length = length + 1
            currentNode = currentNode.next
        return length

    def IsEmpty(self):
        """4,判断链表是否为空。
        :param: 无。
        :return: 若为空,返回True.
        """
        if self.GetLength() == 0:
            print("该单链表为空!")
            return True
        else:
            return False

    def TraverseElement(self):
        """5,遍历单链表。
        :param: 无。
        :return: 无。
        """
        if self.IsEmpty():
            print("当前链表为空!")
            return
        currentNode = self.head.next
        print("当前单链表为:")
        while currentNode is not None:  # 从第一个元素结点开始输出
            print(currentNode.data, end="->")
            currentNode = currentNode.next
        print("")

    def Create(self):
        """6,尾插法创建单链表。
        :param: 无。
        :return: 无。
        """
        print("正在创建单链表......")
        currentNode = self.head
        element = input("输入数据,按#结束:")
        while element != "#":
            newNode = Node(element)
            currentNode.next = newNode
            currentNode = currentNode.next
            element = input("输入数据,按#结束:")
        self.TraverseElement()

    def InsertElementInTail(self, key):
        """7,尾插法插入元素。
        :param: 待从尾部插入的结点的数据key。
        :return: 插入失败,返回False。
        """
        print("即将把{}插入到单链表尾部......".format(key))
        if key == "#":
            return False
        currentNode = self.head
        newNode = Node(key)
        while currentNode.next is not None:  # 结束后currentNode指向最后一个结点
            currentNode = currentNode.next
        currentNode.next = newNode  # 插入新结点
        self.TraverseElement()

    def InsertElementInHead(self, key):
        """8,头插法插入元素。
        :param: 待从头部插入的结点的数据key。
        :return: 插入失败,返回False。
        """
        print("即将把{}插入到单链表头部......".format(key))
        if key == "#":
            return False
        currentNode = self.head
        newNode = Node(key)
        newNode.next = currentNode.next
        currentNode.next = newNode
        self.TraverseElement()

    def InsertElementInSpecifiedPosition(self, key, position):
        """9,在指定位置插入结点。
        :param: 待插入的结点的数据key。待插入的结点在单链表中的位置position
        :return: 插入成功,返回True。
        """
        print("即将把{}插入到单链表第{}位......".format(key, position))
        cursor = 0
        currentNode = self.head
        position = int(position)
        newNode = Node(key)
        if (position < 1) or (position > self.GetLength()):
            print("位置不合法!请重新确定位置!")
            return False
        while currentNode.next is not None:
            cursor += 1
            if cursor == int(position):
                newNode.next = currentNode.next
                currentNode.next = newNode
                self.TraverseElement()
                return True
            else:
                currentNode = currentNode.next

    def GetElement(self, position):
        """10,获取指定位置结点的元素值。
        :param: 待查找的位置position。
        :return: 获取成功,返回指定位置的元素值data。
        """
        print("正在获取第{}位的元素......".format(position))
        cursor = 0
        currentNode = self.head.next
        position = int(position)
        if (position < 1) or (position > self.GetLength()):
            print("位置不合法!请重新确定位置!")
            return False
        while currentNode is not None:
            cursor += 1
            if cursor == int(position):
                print("该位置的元素为:", currentNode.data)
                return currentNode.data
            else:
                currentNode = currentNode.next

    def SetElement(self, key, position):
        """11,设置指定位置的元素。
        :param: 指定元素值key,指定位置position。
        :return: 设置成功,返回True.
        """
        print("正在将第{}位结点的数据元素设置为{}......".format(position, key))
        cursor = 0
        currentNode = self.head.next
        position = int(position)
        if (position < 1) or (position > self.GetLength()):
            print("位置不合法!请重新确定位置!")
            return False
        while currentNode is not None:
            cursor += 1
            if cursor == int(position):
                currentNode.data = key
                return True
            else:
                currentNode = currentNode.next

    def FindPosition(self, key):
        """12,查找指定元素的位置。
        :param: 待查找位置的元素值key。
        :return: 查找成功,返回元素所在的位置Position。
        """
        print("正在获取元素{}所在的位置......".format(key))
        Position = []
        cursor = 0
        currentNode = self.head
        if self.IsEmpty():
            print("当前单链表为空!无法查找!")
            return False
        while currentNode.next is not None:
            currentNode = currentNode.next
            cursor += 1
            if currentNode.data == key:
                Position.append(cursor)
        if Position:
            print("查找成功,值为", key, "的结点位于该单链表的第", Position, "位。")
            return Position
        else:
            print("查找失败!当前单链表中不存在含有", key, "的结点")
            return False

    def DeleteElementInSpecifiedPosition(self, position):
        """13,删除指定位置的结点。
        :param: 待删除的位置position。
        :return: 删除成功,返回被删除的元素值key。
        """
        print("即将删除单链表第{}位......".format(position))
        cursor = 0
        key = None
        currentNode = self.head
        position = int(position)
        if self.IsEmpty():
            print("当前单链表为空!无法删除结点!")
            return False
        if (position < 1) or (position > self.GetLength()):
            print("位置不合法!请重新确定位置!")
            return False
        while currentNode.next is not None:
            removedNode = currentNode.next
            cursor += 1
            if cursor == position:
                currentNode.next = removedNode.next
                key = removedNode.data
                del removedNode
                currentNode = currentNode.next
                self.TraverseElement()
                return key
            else:
                currentNode = currentNode.next

    def DeleteElement(self, key):
        """14,删除所有包含指定元素的结点。
        :param: 待删除结点的值key。
        :return: 被删除的节点的位置Position。
        """
        print("即将删除元素{}......".format(key))
        Position = []
        cursor = 0
        if self.IsEmpty():
            print("当前单链表为空!")
            return False
        currentNode = self.head
        while currentNode.next is not None:
            removedNode = currentNode.next
            cursor += 1
            if int(removedNode.data) == key:  # 假设数据元素都是整型数值类型
                Position.append(cursor)
                currentNode.next = removedNode.next
                del removedNode
            else:
                currentNode = currentNode.next
        print("被删除的节点的位置为", Position)
        self.TraverseElement()
        return Position

    def ClearSingleLinkedList(self):
        """15,清空当前单链表。
        :param: 无。
        :return: 无。
        """
        print("正在清空该链表...")
        self.head = Node("这是头结点的数据")
        print("已清空该单链表!")

    def DestroySingleLinkedList(self):
        """16,销毁当前单链表。
        :param: 无。
        :return: 无。
        """
        print("正在销毁该链表...")
        del self.head
        print("已销毁该单链表!")

    def RverseSingleLinkedList(self):
        """17,逆置当前单链表。
        :param: 无。
        :return: 成功,返回True。
        """
        print("正在逆置单链表......")
        head = self.head
        cursor = self.head.next
        head.next = None
        while cursor is not None:
            pre_cursor = cursor.next
            cursor.next = head.next
            head.next = cursor
            cursor = pre_cursor
        self.TraverseElement()
        return True


if __name__ == '__main__':
    sl = SingleLinkedList()
    sl.Create()
    sl.GetLength()
    sl.InsertElementInTail(5)
    sl.InsertElementInHead(0)
    sl.InsertElementInSpecifiedPosition(-1, 1)
    sl.GetElement(1)
    sl.FindPosition(-1)
    sl.RverseSingleLinkedList()
    sl.DeleteElementInSpecifiedPosition(1)
    sl.DeleteElement(4)
    sl.ClearSingleLinkedList()
    sl.DestroySingleLinkedList()

>>>
正在创建单链表......
输入数据,按#结束:1
输入数据,按#结束:2
输入数据,按#结束:3
输入数据,按#结束:4
输入数据,按#结束:4
输入数据,按#结束:#
当前单链表为:
1->2->3->4->4->
即将把5插入到单链表尾部......
当前单链表为:
1->2->3->4->4->5->
即将把0插入到单链表头部......
当前单链表为:
0->1->2->3->4->4->5->
即将把-1插入到单链表第1......
当前单链表为:
-1->0->1->2->3->4->4->5->
正在获取第1位的元素......
该位置的元素为: -1
正在获取元素-1所在的位置......
查找成功,值为 -1 的结点位于该单链表的第 [1] 位。
正在逆置单链表......
当前单链表为:
5->4->4->3->2->1->0->-1->
即将删除单链表第1......
当前单链表为:
4->4->3->2->1->0->-1->
即将删除元素4......
被删除的节点的位置为 [1, 2]
当前单链表为:
3->2->1->0->-1->
正在清空该链表...
已清空该单链表!
正在销毁该链表...
已销毁该单链表!

3,单表特点总结

(1)不需要移动元素

链表最大特点是插入与删除的效率高,因为不用移动已存在的元素的位置,插入操作与删除操作本身的时间复杂度是O(1)。

(2)存储密度不高

因为链表中的每个结点不完全用于存储数据元素,所以链表的存储密度不高。

(3)无法随机访问

因为链表采用链式存储结构,对数据元素的访问需要先沿着链结构逐一定位,所以不支持随机访问,访问元素的时间复杂度为O(n)。

(二)循环单链表

1,循环单链表的概念

链表结点只有一个指向后继结点的指针域且尾结点指针指向头结点的链表叫循环单链表。
在这里插入图片描述

2,循环单链表的实现

class Node(object):
    """初始化结点
    """
    def __init__(self, data):
        self.data = data
        self.next = None


class CircularSingleLinkedList(object):
    """带头结点的循环单链表
    """

    def __init__(self):
        """初始化头结点
        """
        self.head = Node("头结点")

    def GetLength(self):
        """获取循环单链表长度
        """
        cursorNode = self.head
        length = 0
        while cursorNode.next != self.head:
            length += 1
            cursorNode = cursorNode.next
        return length

    def IsEmpty(self):
        """判断链表是否为空
        """
        if self.GetLength() == 0:
            return True
        else:
            return False

    def Traval(self):
        """遍历循环单链表
        """
        if self.IsEmpty():
            print("当前链表为空!")
            return
        cursorNode = self.head.next
        print("当前链表为:")
        print(self.head.data, end="->")
        while cursorNode != self.head:
            print(cursorNode.data, end="->")
            cursorNode = cursorNode.next
            if cursorNode == self.head:
                print(self.head.data)

    def Create(self):
        """尾插法创建循环单链表
        """
        element = input("输入结点数据,按#结束:")
        cursorNode = self.head
        while element != '#':
            newNode = Node(element)
            cursorNode.next = newNode
            cursorNode = cursorNode.next
            cursorNode.next = self.head
            element = input("输入结点数据,按#结束:")
        self.Traval()

    def InsertElementInTail(self):
        """尾插
        """
        element = input("待从尾部插入的结点的数据:")
        if element == "#":
            return
        cursorNode = self.head
        newNode = Node(element)
        while cursorNode.next != self.head:
            cursorNode = cursorNode.next
        newNode.next = cursorNode.next
        cursorNode.next = newNode
        self.Traval()

    def InsertElementInHead(self):
        """头插
        """
        element = input("待从头部插入的结点的数据:")
        if element == "#":
            return
        currentNode = self.head
        newNode = Node(element)
        newNode.next = currentNode.next
        currentNode.next = newNode
        self.Traval()

    def InsertElementInSpecifiedPosition(self):
        """在指定位置插入结点
        """
        Pos = 0
        currentNode = self.head
        element, position = input("结点的数据 待插入的结点在循环单链表中的位置").split(" ")
        newNode = Node(element)
        if int(position) < 1 or int(position) > self.GetLength():
            print("位置不合法!请重新确定位置!")
            return
        while currentNode.next != self.head:
            Pos += 1
            if Pos == int(position):
                newNode.next = currentNode.next
                currentNode.next = newNode
                self.Traval()
                return
            else:
                currentNode = currentNode.next
        self.Traval()

    def FindElement(self):
        """查找所有有指定数据的结点的位置
        """
        Position = []
        Pos = 0
        currentNode = self.head
        element = input("待查找的数据:")
        if self.IsEmpty():
            print("当前循环单链表为空!无法查找!")
            return
        while currentNode.next != self.head:
            currentNode = currentNode.next
            Pos += 1
            if currentNode.data == element:
                Position.append(Pos)
        if Position:
            print("查找成功,值为", element, "的结点位于该循环单链表的第", Position, "位。")
        else:
            print("查找失败!当前循环单链表中不存在含有", element, "的结点")

    def DeleteElementInSpecifiedPosition(self):
        """在指定位置删除结点
        """
        print("在指定位置删除结点")
        Pos = 0
        currentNode = self.head
        position = int(input("待删除的位置:"))
        if self.IsEmpty():
            print("当前循环单链表为空!无法删除结点!")
            return
        if position < 1 or position > self.GetLength():
            print("位置不合法!请重新确定位置!")
            return
        while currentNode.next != self.head:
            removedNode = currentNode.next
            Pos += 1
            if Pos == position:
                currentNode.next = removedNode.next
                del removedNode
            else:
                currentNode = currentNode.next
        self.Traval()

    def DeleteElement(self):
        """删除所有有指定数据的结点
        """
        if self.IsEmpty():
            print("当前循环单链表为空!")
            return
        element = input('请输入待删除结点的值:')
        currentNode = self.head
        while currentNode.next != self.head:
            removedNode = currentNode.next
            if removedNode.data == element:
                currentNode.next = removedNode.next
                del removedNode
            else:
                currentNode = currentNode.next
        print("成功删除所有含值为", element, "的结点")
        self.Traval()

    def Destory(self):
        print("正在销毁该链表...")
        del self.head
        print("已销毁该循环单链表 !")


if __name__ == '__main__':
    csl = CircularSingleLinkedList()
    csl.Create()
    csl.InsertElementInTail()
    print(csl.GetLength())
    csl.InsertElementInHead()
    csl.FindElement()
    csl.DeleteElementInSpecifiedPosition()
    csl.DeleteElement()

>>>
输入结点数据,按#结束:1
输入结点数据,按#结束:2
输入结点数据,按#结束:3
输入结点数据,按#结束:4
输入结点数据,按#结束:4
输入结点数据,按#结束:#
当前链表为:
头结点->1->2->3->4->4->头结点
待从尾部插入的结点的数据:5
当前链表为:
头结点->1->2->3->4->4->5->头结点
6
待从头部插入的结点的数据:0
当前链表为:
头结点->0->1->2->3->4->4->5->头结点
待查找的数据:4
查找成功,值为 4 的结点位于该循环单链表的第 [5, 6] 位。
在指定位置删除结点
待删除的位置:5
当前链表为:
头结点->0->1->2->3->4->5->头结点
请输入待删除结点的值:5
成功删除所有含值为 5 的结点
当前链表为:
头结点->0->1->2->3->4->头结点

(三)双链表

1,双链表的概念

在这里插入图片描述

2,双链表的实现

class DoubleLinkedNode(object):
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None


class DoubleLinkedList(object):
    def __init__(self):
        self.head = DoubleLinkedNode("头结点")

    def GetLength(self):
        """获取双链表长度
        """
        currentNode = self.head.next
        length = 0
        while currentNode is not None:
            length += 1
            currentNode = currentNode.next
        return length

    def IsEmpty(self):
        """判断链表是否为空
        """
        if self.GetLength() == 0:
            print("该链表为空!")
            return True
        else:
            return False

    def Traval(self):
        """遍历双链表
        """
        if self.IsEmpty():
            return
        currentNode = self.head
        print("当前链表为:")
        while currentNode is not None:
            print(currentNode.data, end="<->")
            currentNode = currentNode.next
        print("")

    def Create(self):
        data = input("请输入元素:")
        cNode = self.head
        while data != '#':
            nNode = DoubleLinkedNode(data)
            cNode.next = nNode
            nNode.prev = cNode
            cNode = nNode
            data = input("请输入元素:")
        self.Traval()

    def InsertElementInTail(self):
        """尾插法
        """
        element = input("待从尾部插入的结点的数据:")
        if element == "#":
            return
        currentNode = self.head
        newNode = DoubleLinkedNode(element)
        while currentNode.next is not None:
            currentNode = currentNode.next
        currentNode.next = newNode
        newNode.prev = currentNode
        self.Traval()

    def InsertElementInHead(self):
        """头插法
        """
        element = input("待从头部插入的结点的数据:")
        if element == "#":
            return
        currentNode = self.head
        newNode = DoubleLinkedNode(element)
        newNode.next = currentNode.next
        currentNode.next = newNode
        newNode.prev = currentNode
        self.Traval()

    def InsertElementInSpecifiedPosition(self):
        """在指定位置插入结点
        """
        Pos = 0
        currentNode = self.head
        element, position = input("结点的数据 待插入的结点在双链表中的位置").split(" ")
        newNode = DoubleLinkedNode(element)
        if int(position) < 1 or int(position) > self.GetLength() + 1:
            print("位置不合法!请重新确定位置!")
            return
        while currentNode.next is not None:
            Pos += 1
            if Pos == int(position):
                newNode.next = currentNode.next
                currentNode.next = newNode
                newNode.prev = currentNode
                self.Traval()
                return
            else:
                currentNode = currentNode.next

    def FindElement(self):
        """查找所有有指定数据的结点的位置
        """
        Position = []
        Pos = 0
        currentNode = self.head
        element = input("待查找的数据:")
        if self.IsEmpty():
            print("当前双链表为空!无法查找!")
            return
        while currentNode.next is not None:
            currentNode = currentNode.next
            Pos += 1
            if currentNode.data == element:
                Position.append(Pos)
        if Position:
            print("查找成功,值为", element, "的结点位于该双链表的第", Position, "位。")
        else:
            print("查找失败!当前双链表中不存在含有", element, "的结点")

    def DeleteElementInSpecifiedPosition(self):
        """在指定位置删除结点
        """
        print("在指定位置删除结点")
        Pos = 0
        currentNode = self.head
        position = int(input("待删除的位置:"))
        if self.IsEmpty():
            print("当前双链表为空!无法删除结点!")
            return
        if position < 1 or position > self.GetLength():
            print("位置不合法!请重新确定位置!")
            return
        while currentNode.next is not None:
            removedNode = currentNode.next
            Pos += 1
            if Pos == position:
                currentNode.next = removedNode.next
                if removedNode.next is None:
                    del removedNode
                else:
                    removedNode.next.prev = currentNode
                    del removedNode
            else:
                currentNode = currentNode.next
        self.Traval()

    def DeleteElement(self):
        """删除所有有指定数据的结点
        """
        if self.IsEmpty():
            print("当前双链表为空!")
            return
        element = input('请输入待删除结点的值:')
        currentNode = self.head
        while currentNode.next is not None:
            removedNode = currentNode.next
            if removedNode.data == element:
                currentNode.next = removedNode.next
                if currentNode.next is None:
                    del removedNode
                else:
                    removedNode.next.prev = currentNode
                    del removedNode
            else:
                currentNode = currentNode.next
        print("成功删除所有含值为", element, "的结点")
        self.Traval()

    def Destory(self):
        print("正在销毁该链表...")
        del self.head
        print("已销毁该双链表!")

if __name__ == '__main__':
    dl = DoubleLinkedList()
    dl.Create()
    print(dl.GetLength())
    dl.InsertElementInTail()
    print(dl.GetLength())
    dl.InsertElementInHead()
    print(dl.GetLength())
    dl.InsertElementInSpecifiedPosition()
    print(dl.GetLength())
    dl.FindElement()
    print(dl.GetLength())
    dl.DeleteElementInSpecifiedPosition()
    print(dl.GetLength())
    dl.DeleteElement()
    print(dl.GetLength())

>>>
请输入元素:1
请输入元素:2
请输入元素:3
请输入元素:4
请输入元素:4
请输入元素:5
请输入元素:#
当前链表为:
头结点<->1<->2<->3<->4<->4<->5<->
6
待从尾部插入的结点的数据:6
当前链表为:
头结点<->1<->2<->3<->4<->4<->5<->6<->
7
待从头部插入的结点的数据:0
当前链表为:
头结点<->0<->1<->2<->3<->4<->4<->5<->6<->
8
结点的数据 待插入的结点在双链表中的位置7 8
当前链表为:
头结点<->0<->1<->2<->3<->4<->4<->5<->7<->6<->
9
待查找的数据:4
查找成功,值为 4 的结点位于该双链表的第 [5, 6] 位。
9
在指定位置删除结点
待删除的位置:8
当前链表为:
头结点<->0<->1<->2<->3<->4<->4<->5<->6<->
8
请输入待删除结点的值:4
成功删除所有含值为 4 的结点
当前链表为:
头结点<->0<->1<->2<->3<->5<->6<->
6

(四)循环双链表

1,循环双链表的概念

在这里插入图片描述

2,循环双链表的实现

class DoubleLinkedNode(object):
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None


class CircularDoubleLinkedList(object):
    def __init__(self):
        self.head = DoubleLinkedNode("头结点")

    def GetLength(self):
        """获取循环双链表长度
        """
        currentNode = self.head.next
        length = 0
        while currentNode != self.head:
            length += 1
            currentNode = currentNode.next
        return length

    def IsEmpty(self):
        """判断循环双链表是否为空
        """
        if self.GetLength() == 0:
            return True
        else:
            return False

    def Traval(self):
        """遍历循环双链表
        """
        if self.IsEmpty():
            print("当前链表为空!")
            return
        currentNode = self.head
        print("当前链表为:")
        while currentNode.next != self.head:
            print(currentNode.data, end="<->")
            currentNode = currentNode.next
            if currentNode.next == self.head:
                print(currentNode.data, end="<->")
                print(self.head.data)

    def Create(self):
        data = input("请输入元素:")
        cNode = self.head
        while data != '#':
            nNode = DoubleLinkedNode(data)
            nNode.next = cNode.next
            cNode.next = nNode
            nNode.prev = cNode
            cNode = nNode
            data = input("请输入元素:")
        cNode.next = self.head
        self.head.prev = cNode
        self.Traval()

    def InsertElementInTail(self):
        """尾插法
        """
        element = input("待从尾部插入的结点的数据:")
        if element == "#":
            return
        currentNode = self.head
        newNode = DoubleLinkedNode(element)
        while currentNode.next != self.head:
            currentNode = currentNode.next
        newNode.next = currentNode.next
        currentNode.next = newNode
        newNode.prev = currentNode
        self.head.prev = newNode
        self.Traval()

    def InsertElementInHead(self):
        """头插法
        """
        element = input("待从头部插入的结点的数据:")
        if element == "#":
            return
        currentNode = self.head
        newNode = DoubleLinkedNode(element)
        newNode.next = currentNode.next
        currentNode.next = newNode
        newNode.prev = currentNode
        self.head.prev = newNode
        self.Traval()

    def InsertElementInSpecifiedPosition(self):
        """在指定位置插入结点
        """
        Pos = 0
        currentNode = self.head
        element, position = input("结点的数据 待插入的结点在循环双链表中的位置").split(" ")
        newNode = DoubleLinkedNode(element)
        if int(position) < 1 or int(position) > self.GetLength() + 1:
            print("位置不合法!请重新确定位置!")
            return
        while currentNode.next is not None:
            Pos += 1
            if Pos == int(position):
                newNode.next = currentNode.next
                currentNode.next = newNode
                newNode.prev = currentNode
                if currentNode.next == self.head:
                    self.head.prev = newNode
                self.Traval()
                return
            else:
                currentNode = currentNode.next

    def FindElement(self):
        """查找所有有指定数据的结点的位置
        """
        Position = []
        Pos = 0
        currentNode = self.head
        element = input("待查找的数据:")
        if self.IsEmpty():
            print("当前循环双链表为空!无法查找!")
            return
        while currentNode.next != self.head:
            currentNode = currentNode.next
            Pos += 1
            if currentNode.data == element:
                Position.append(Pos)
        if Position:
            print("查找成功,值为", element, "的结点位于该循环双链表的第", Position, "位。")
        else:
            print("查找失败!当前循环双链表中不存在含有", element, "的结点")

    def DeleteElementInSpecifiedPosition(self):
        """在指定位置删除结点
        """
        Pos = 0
        currentNode = self.head
        position = int(input("待删除的位置:"))
        if self.IsEmpty():
            print("当前循环双链表为空!无法删除结点!")
            return
        if position < 1 or position > self.GetLength():
            print("位置不合法!请重新确定位置!")
            return
        while currentNode.next != self.head:
            removedNode = currentNode.next
            Pos += 1
            if Pos == position:
                currentNode.next = removedNode.next
                if removedNode.next == self.head:
                    currentNode = removedNode.next.prev
                    del removedNode
                else:
                    removedNode.next.prev = currentNode
                    del removedNode
            else:
                currentNode = currentNode.next
        self.Traval()

    def DeleteElement(self):
        """删除所有有指定数据的结点
        """
        if self.IsEmpty():
            print("当前循环双链表为空!")
            return
        element = input('请输入待删除结点的值:')
        currentNode = self.head
        while currentNode.next != self.head:
            removedNode = currentNode.next
            if removedNode.data == element:
                currentNode.next = removedNode.next
                if removedNode.next == self.head:
                    currentNode = removedNode.next.prev
                    del removedNode
                else:
                    removedNode.next.prev = currentNode
                    del removedNode
            else:
                currentNode = currentNode.next
        print("成功删除所有含值为", element, "的结点")
        self.Traval()

    def Destory(self):
        print("正在销毁该链表...")
        del self.head
        print("已销毁该循环双链表!")


if __name__ == '__main__':
    cdl = CircularDoubleLinkedList()
    cdl.Create()
    cdl.InsertElementInTail()
    cdl.InsertElementInHead()
    cdl.InsertElementInSpecifiedPosition()
    cdl.FindElement()
    cdl.DeleteElementInSpecifiedPosition()
    cdl.DeleteElement()
    
>>>
请输入元素:1
请输入元素:2
请输入元素:3
请输入元素:4
请输入元素:4
请输入元素:5
请输入元素:#
当前链表为:
头结点<->1<->2<->3<->4<->4<->5<->头结点
待从尾部插入的结点的数据:6
当前链表为:
头结点<->1<->2<->3<->4<->4<->5<->6<->头结点
待从头部插入的结点的数据:0
当前链表为:
头结点<->0<->1<->2<->3<->4<->4<->5<->6<->头结点
结点的数据 待插入的结点在循环双链表中的位置4 8
当前链表为:
头结点<->0<->1<->2<->3<->4<->4<->5<->4<->6<->头结点
待查找的数据:4
查找成功,值为 4 的结点位于该循环双链表的第 [5, 6, 8] 位。
待删除的位置:9
当前链表为:
头结点<->0<->1<->2<->3<->4<->4<->5<->4<->头结点
请输入待删除结点的值:4
成功删除所有含值为 4 的结点
当前链表为:
头结点<->0<->1<->2<->3<->5<->头结点
  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值