链表及其python实现

链表

链表(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);
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
链栈是基于单链表实现的栈。下面是链栈的基本操作: 1. 初始化链栈:创建一个空链表,将链栈的头指针指向该链表。 2. 判断链栈是否为空:判断链栈的头指针是否为空。 3. 进栈:首先创建一个新节点,将数据存入节点中,然后将新节点插入到链表的头部。 4. 出栈:删除链表的头节点,并返回该节点的数据。 5. 清空链栈:遍历链表,逐一删除链表的每个节点。 6. 获取栈顶元素:返回链表的头节点的数据。 下面是链栈的实现代码: ```python class Node: def __init__(self, data=None): self.data = data self.next = None class LinkedStack: def __init__(self): self.top = Node() def is_empty(self): return self.top.next is None def push(self, data): new_node = Node(data) new_node.next = self.top.next self.top.next = new_node def pop(self): if self.is_empty(): raise Exception("Stack is empty!") else: pop_node = self.top.next self.top.next = pop_node.next return pop_node.data def clear(self): self.top.next = None def get_top(self): if self.is_empty(): raise Exception("Stack is empty!") else: return self.top.next.data ``` 其中,节点类 Node 包括数据域 data 和指针域 next,表示该节点的下一个节点。链栈类 LinkedStack 包括头指针 top,表示链栈的栈顶元素。is_empty() 方法判断链栈是否为空;push(data) 方法插入新节点;pop() 方法删除链表的头节点;clear() 方法清空链栈;get_top() 方法获取链栈的栈顶元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

他是只猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值