当前位置:   article > 正文

数据结构与算法——6. 抽象数据类型:无序表与有序表及其链表实现_有序链表的无序链表的区别

有序链表的无序链表的区别

一、无序表(unordered list)抽象数据类型

1. 无序表的定义

列表是一种数据项按照相对位置存放数据集,有时也称为“无序表unordered list”,其中数据项只按照存放位置来索引,如第1个、第2个……、最后一个等。

如一个考试分数的集合“54, 26, 93, 17, 77和31”,如果用无序表来表示,就是[54, 26, 93, 17, 77, 31]。

2. 采用链表实现无序表

虽然列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的物理存储空间。

因此,我们可以采用链表的结构来实现无序表。

(1)链表

如下图,链表中的数据项存放位置并没有规则,通过在数据项之间建立链接指向,来保持其前后相对位置

在这里插入图片描述

第一个和最后一个数据项需要显式标记出来,一个是队首,一个是队尾。

(2)链表节点

链表实现的最基本元素是节点Node,上图中的head、54、93、end等,就是链表的一个个节点。

每个节点至少要包含2个信息:数据项本身(data),以及指向下一个节点的引用信息(next)

在这里插入图片描述

注意:next为None时,表示没有下一个节点了!

(3)python实现链表节点

class Node:
    def __init__(self):
        self.data = init_data
        self.next = None
        
    def get_data(self):
        """返回当前节点的数据"""
        return self.data
    
    def get_next(self):
        """返回下一个节点的地址"""
        return self.next
    
    def set_data(self, new_data):
        """修改节点数据"""
        self.data = new_data
    
    def set_next(self, new_next):
        """修改下一节点的地址"""
        self.next = new_next
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

(4)python实现链表

先来分析一下步骤:

  • 链表的第一个和最后一个节点最重要

    如果想访问到链表中的所有节点,就必须从第一个节点开始沿着链接遍历下去。所以无序表必须要有对第一个节点的引用信息。

  • 添加数据项:

    由于无序表并没有限定数据项之间的顺序,出于对性能的考虑,应添加到表头head节点上。
    在这里插入图片描述

​ 注意:两步的顺序不要搞反!否则会丢失head对节点93的引用。

  • 统计数据项的数量:

    从链表头head开始遍历到表尾同时用变量累加经过的节点个数。

  • 搜索数据项是否在链表中:

    从链表头head开始遍历到表尾,同时判断当前节点的数据项是否目标。

  • 移除数据项:

    首先要找到item,这个过程跟上面的的搜索方法一样,但在删除节点时,需要特别的技巧。

    在这里插入图片描述

    需要把前一个节点的next指向current的下一个节点

完整的代码如下:

class UnorderedList:

    def __init__(self):
        self.head = None

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

    def add(self,item):
        """添加数据项"""
        temp = Node(item)
        # 步骤顺序千万不要搞错
        temp.set_next(self.head)
        self.head = temp

    def size(self):
        """返回链表大小"""
        current = self.head
        count = 0
        while current != None:
            count = count + 1
            current = current.get_next()

        return count

    def search(self,item):
        """查询链表是否包含指定数据项"""
        current = self.head
        found = False
        while current != None and not found:
            if current.get_data() == item:
                found = True
            else:
                current = current.get_next()

        return found

    def remove(self,item):
        """移除指定元素"""
        current = self.head
        previous = None
        found = False
        while not found:
            if current.get_data() == item:
                found = True
            else:
                previous = current
                current = current.get_next()

        if previous == None:
            self.head = current.get_next()
        else:
            previous.set_next(current.get_next())

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

二、有序表(Ordered List)抽象数据类型

1. 有序表的定义

有序表是一种数据项依照其某可比性质(如整数大小、字母表先后)来决定在列表中的位置。

2. 使用python实现有序表

下面对数据项的讨论并不仅适用于整数,可适用于所有定义了__gt__方法(即>操作符)的数据类型。

同样采用链表方法实现有序表,Node定义相同。需要记住的是,数据项的相对位置,取决于它们之间的“大小”比较。

有序表的节点与无序表的一样,并且大部分方法与无序表的方法也一样,只有search方法和add方法有所不同:

search方法:

  • 在无序表的search中,如果需要查找的数据项不存在,则会搜遍整个链表,直到表尾;

  • 对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查找时间。

    一旦当前节点的数据项大于(或小于)所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False。

    def search(self,item):
            current = self.head
            found = False
            stop = False
            while current != None and not found and not stop:
                if current.get_data() == item:
                    found = True
                else:
                    if current.get_data() > item:
                        stop = True
                    else:
                        current = current.get_next()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

add方法:

  • 相比无序表,有序表添加数据项时,必须保证加入的数据项添加在合适的位置,以维护整个链表的有序性。

  • 以从小到大的顺序为例:需要先找到恰好大于新数据项的数据项,然后将新数据项插入该数据项的前面。

    在这里插入图片描述

    def add(self,item):
        current = self.head
        previous = None
        stop = False
        while current != None and not stop:
            if current.get_data() > item:
                stop = True
            else:
                previous = current
                current = current.get_next()
    
        temp = Node(item)
        if previous == None:
            temp.set_next(self.head)
            self.head = temp
        else:
            temp.set_next(current)
            previous.set_next(temp)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/328929
推荐阅读
相关标签
  

闽ICP备14008679号