链表及其python实现

链表及其python实现,第1张

链表及其python实现

文章目录
  • 链表
  • 采用链表来实现无序表
    • 实现节点ListNode
    • 链表实现无序表UnorderList
  • 有序表及其实现
  • 总结

链表

链表(linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。

由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。

数组是很常用的数据储存方式,而链表就是继数组之后,第二种最通用的数据储存方式了。数组需要存放在连续的空间,计算机很容易实现。而链表的好处是不用确定空间长度,不够的时候,直接申请新的节点,帮助插入。所以链表可以更灵活地进行内存分配。

链表(linked list)是一种序列形的数据结构,其中包含了很多通过链接 (link) 被串起来的节点。每个节点有一个数据域,储存着节点的数值,还有一个指针域,指向下一个节点。

  1. 单链表:链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。

  2. 双链表:双链表是为了解决链表节点不知道前面节点的尴尬,于是在节点的定义中,存在一个父节点,和一个子节点。这样就能顺着父节点往回找。

  3. 循环链表:在一个 循环链表中, 首节点和末节点被连接在一起。这种方式在单向和双向链表中皆可实现。

    主要应用:链表用来构建许多其它数据结构,如堆栈,队列和他们的派生。

采用链表来实现无序表
  • 数据存放位置美哦与规则,数据项之间建立链接指向,保持相对位置;
  • 每个节点至少包含两个信息:数据项本身,及指向下一个节点的引用信息。

实现节点ListNode
class ListNode(object):
	# 初始化
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
	# 返回数据项
    def get_Val(self):
        return self.val
	# 返回下一个节点
    def get_Next(self):
        return self.next
	# 修改数据项
    def set_Val(self,newval):
        self.val = newval
	# 修改下一个节点
    def set_Next(self,newnext):
        self.next = newnext
链表实现无序表UnorderList
  • 链接节点构建数据集;
  • 如果想要访问列表中的所有节点,就必须从第一个遍历下去;

无序表必须引用第一个节点:

class UnorderList(object):
    def __init__(self):
        self.head = None

判断表是否为空

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

add方法
我们给链表添加数据,新数据项可以加入到原表的任何位置,考虑性能,我们添加到最容易添加的地方,表头。
size()方法
从链条头head开始遍历到表尾用变量累加经过的节点数。
search方法
从表头head开始遍历到表尾,同时判断当前节点的数据项是否是目标。
remove方法
首先找到目标,然后current指向当前匹配的数据项的节点;然后把前一个节点的next指向下一个节点;所有这里需要当前节点还有前一个节点的引用。

class UnorderList(object):
    def __init__(self):
        self.head = ListNode()

    def isEmpty(self):
        return self.head.val == None

    def add(self, item):
        newnode = ListNode(item, None)
        newnode.set_Next(self.head)
        self.head = newnode

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count = count + 1
            current = current.get_Next()
        return count-1

    def search(self, item):
        current = self.head
        found = False
        while current != None and not found:
            if current.get_Val() == 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_Val() == 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())
l = UnorderList()
print(l.isEmpty())
l.add(4)
l.add(5)
l.add(6)
print(l.size())
l.remove(6)
print(l.search(5))
print(l.size())
输出:
True
3
True
2
有序表及其实现

有序表是一种数据项按照其可比性质(如整数大小、字母先后)来决定在列表中的位置;越小的数据项越靠近表头,越靠前。

对比无序表,可以发现节点定义相同,对于isEmpty、size、remove这些方法与节点次序是无关的,所以两者相同;

而search/add方法需要修改。

  • 在无序表中,查找需要遍历所有链表;而有序表则不需要,因为当前节点数据项大于所查找的数据后就不需要向后查找了(链表有序排列特性);
  • add方法在添加数据时,需要添加到合适位置,不能仅仅是添加在表头了,保证链表的有序性。
def add(self, item):
    current = self.head
    previous = None
    stop = False

    while current.get_Val() != None and not stop:
        if current.get_Val() > item:
            stop = True
        else:
            previous = current
            current = current.get_Next()
    temp = ListNode(item, None)
    if previous == None:
        temp.set_Next(self.head)
        self.head = temp
    else:
        temp.set_Next(current)
        previous.set_Next(temp)
def search(self, item):
    current = self.head
    found = False
    stop = False
    while current != None and not found and not stop:
        if current.get_Val() == item:
            found = True
        else:
            if current.get_Val() > item:
                stop = True
            else:
                current = current.get_Next()
    return found
总结
  1. 对于链表的复杂度,主要看对应的方法是否涉及到链表的遍历;
    isEmpty是O(1);size是O(n);
    search/remove/add(有序)O(n);

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5571699.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存