...

Python实现单链表增删改查

Python实现单链表

自己在看书的时候忘记是哪个老师说的,数据归根到底其实就是2种,一种是链表,一种是数组。其他的什么栈堆队列集合都是从这两种数据类型转换过来的。那今天我就开始自己写写试试看吧。从今天开始重新苦逼的算法之路。第一路就是单链表的实现,什么是单链表呢。节点就是一个有头有身体的数据,这个头连接的就是自己的上一个链表的位置。

参考网页:https://www.tutorialspoint.com/python_ata_structure/python_linked_lists.htm
从上面的图可以看出来,其实链表除了头和尾都有一个分为两部分。链表也分为单链表,双链表,循环链表,非循环列表。
这一次就实现最简单的单链表。根据万能的增删改查定律,一个链表我们只要实现了增删改查遍历啥的差不多就能说是实现了。比如我们用的Python的什么集合和列表还有元祖,本质上不就是进行操作各种数据的增删改查吗?

""" 新建一个节点类  
包含数据和尾巴(默认为空) """  
class Node(object):  
    def __init__(self, data):  
        self.data = data # 数据位置  
        self.next = None # 表示信息  


""" 新建一个单链表   
单链表上有个头"""  
class SingleLinkedList(object):  
    # 初始化生成链表的头,私有是因为不想轻易被改变  
    def __init__(self, node=None):  
        self.__head = node  


    """ 判断是否为空  
    head指向了默认的node  
    初始化的时候已经生成了一个__head,指向了空  
    所以判断是否为空的时候就要判断头是否为空  
    因为不为空的链表的头,应该是有数的,并且指向前面的屁股   
    """  
    def is_empty(self):  
        return self.__head == None  


    """ 链表长度  
    思路:  
    链表头复制给current->设置一个count用来计数->while判断  
    -> 只要current不为None 意思就是只要现在不是尾巴 没到头  
    -> 计数+1->然后current.next就要赋值给current  
    -> 因为链表的特性:尾巴就是下一个链表的头   
    """  
    def length(self):  
        current = self.__head  
        count = 0  
        while current != None:  
            count += 1  
            current = current.next  
        return count  


    """ 遍历  
    思路:  
    其实遍历的思路和上面的计算长度几乎差不多,都是头判断然后进行输出  
    赋值头部 -> 进行判断是否为最后一个-> 不是就进行打印  
    -> current.next就要赋值给current-> 因为链表的特性:尾巴就是下一个链表的头   
    """  
    def travel(self):  
        current = self.__head  
        while current != None:  
            print(current.data)  
            current = current.next  


    """ 尾部添加  
    新建一个节点  
    判断链表是否为空  
    不为空,就现在新建的链表头指向前面链表的屁股  
    前面的链表是什么呢?如果没有这个疑问,很容易就会写错  
    前面的链表其实就是现在链表的最后一个  
    最后一个是什么呢,最后一个孤独的链表就是没有尾巴的链表  
    没有尾巴的链表就是next没有任何值的链表   
    """  
    def append(self, data):  
        node = Node(data)  
        if self.is_empty():  
            self.__head = node  
        else:  
            current = self.__head  
            while current.next != None:  
                current = current.next  
                # 到这里都是一直向下走  
                # 这里基本表示走到了尽头  
            current.next = node  


    """ 头部添加 """  
    def add(self,data):  
        # 新建节点  
        node = Node(data)  
        # 新建节点的尾巴指向现在链表的头  
        node.next = self.__head  
        # 于是孤独节点的头就成了现在的头  
        self.__head = node  


    """ 添加到指定位置  
    positon:头插(add) 尾插(append) 中间插入 位置是索引int  
    data:节点数据  
    """  
    def insert(self, position, data):  
        if position <= 0:  
            self.add(data) # 直接使用上面定义的  
        elif position > (self.length()-1):  
            self.append(data)  
        else:  
            node = Node(data)  
            count = 0  
            # 记录插入位置的前一个位置  
            # [4,6,7,2,3] 假设输入position是2  
            # [4,6,X,7,2,3] 那是不是就要找到6的位置 pre就是这个位置  
            pre = self.__head  
            while count < (position -1):  
                count += 1  
                # 下一个列表的前面就是后面  
                pre = pre.next # self.__head.next  
            node.next = pre.next  
            pre.next = node  


    """ 查找节点  
    判断是否为空,为空直接False  
    继续遍历向下走   
    """  
    def search(self, data):  
        current = self.__head  
        while current != None:  
            if current.data == data:  
                return True  
            current = current.next  
        return False      

    """ 删除节点  
    删除要先查找到  
    然后进行删除  
    最重要的是将链表继续串起来  
    """  
    def remove(self, data):  
        # 链表从头开始  
        current = self.__head  
        # 设置一个前面 目前默认为空  
        pre = None  
        # 只要不是最后一个  
        while current != None:  
            # 如果找到了节点  
            if current.data == data:  
                # 找到了节点 判断是否为第一个  
                if not pre:  
                    # 不是第一个,就把现在的头直接指向下一个节点  
                    # 现在节点的next,如果是现在节点就是current而不是current.next了  
                    self.__head = current.next  
                else:  
                    # 是第一个,直接让头pre头部指向下一个节点  
                    pre.next = current.next  
                break # 找到了就要立刻退出!  
            else:  
                # 如果没找到节点,pre指向现在的节点  
                # 继续向下走  
                pre = current   
                current = current.next  

# 测试一下上面的代码是否成立  
if __name__ == '__main__':  
    singlist = SingleLinkedList()  
    print("是否为空:",singlist.is_empty())  
    print("长度为:",singlist.length())  
    print("开始添加数字5")  
    singlist.append(5)  
    print("是否为空:",singlist.is_empty())  
    print("长度为:",singlist.length())  
    print("尾部添加数字7,8,10")  
    singlist.append(7)  
    singlist.append(8)  
    singlist.append(10)  
    print("开始遍历")  
    singlist.travel()  
    print("头部添加数字800")  
    singlist.add(800)  
    singlist.insert(2,233)  
    print("开始遍历")  
    singlist.travel()  
    print("查找是否有233:",singlist.search(233))  
    print("移除一个10")  
    singlist.remove(10)  
    print("开始遍历")  
    singlist.travel()  

共有评论(0)

登陆即可评论哦