算法入门(七,数据结构,单向链表与双链表)

Posted 韶光不负

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门(七,数据结构,单向链表与双链表)相关的知识,希望对你有一定的参考价值。

链表结构

什么是链表?

链表是一种物理存储单元上非连续,非顺序的存储结构(数据元素的逻辑顺序是通过链表中的指针链就=接次序实现的)链表由一系列结点组成,结点可以在运行时动态生成。

什么是结点?

结点由二部分组成,一个是存储数据单元的数据域,一个是存储下一个节点的指针(连接区)。

python创建一个元素为节点,使用类改变数据类型。

#定义为结点对象
class Node:
    def __init__(self,val):
        #val存放数据元素
        self.val=val
        #next存放下一个节点的标识符
        self.next=None

链表的作用

链表结构可以充分利用计算机的内部空间,实现灵活的内存动态管理。

链表与顺序表的操作复杂度对比

链表失去了顺序表随机读取的优点,同时链表增加了结点的指针域。空间开销大,但是对存储空间的使用相对灵活。

链表与顺序表的对比
操作链表顺序表
访问元素O(n)O(1)
在头部插入/删除O(1)O(n)
在末部插入/删除O(n)O(1)
在中间插入/删除O(n)O(n)

单向链表

理解:单向的,指针头指向尾部

实现方式:(python)

'''
    单链表的实现

'''
#创建结点对象
class Node:
    def __init__(self,val):
        self.val=val
        self.next=None

class Singly_linked_list():
    #数组头节点创建,node=None声明没有元素
    def __init__(self,node=None):
        #__head私有化属性,不被外界访问
        self.__head=node

    #判断是否为空
    def is_empty(self):
        #判断头是否为空
        return self.__head==None

    #查看链表有多少个元素
    def length(self):
        #cur指向头
        cur=self.__head
        #记录有多少元素
        count=0
        #判断链表是否为空
        while cur != None:
            #不是加一
            count+=1
            #指针cur向后移动
            cur=cur.next
        return count
    #头部插入
    def headadd(self,val):
        #构建节点(将插入数值换成结点类型,)
        node=Node(val)
        #设置关联,头指向下一个,不能交换位置,交换位置会改变原本链表的连接关系
        #先改变元素next区域,在指向头
        node.next=self.__head
        self.__head=node

    #中间插入
    def middleadd(self,pos,val):
        if pos == 0:
            # 当pos=o是就是头部添加
            self.headadd(val)
        elif pos >=self.length()-1:
            # 当 pos大于链表长度就是尾部部添加
            self.tailadd(val)
        else:
            pre = self.__head
            #构建pre指针指向头节点的值
            count=0
            while count < (pos-1):
                count+=1
                pre=pre.next
            node=Node(val)
            node.next=pre.next
            pre.next=node

    #尾部插入
    def tailadd(self,val):
        node = Node(val)
        cur=self.__head
        #如果链表中没有元素
        if cur is None:
            self.headadd(val)
        else:
            while cur.next is not None:
                cur=cur.next
            cur.next=node


    #删除节点
    def remove(self,item):
        cur=self.__head
        pre=None
        while cur !=None:
        #遍历一遍
            if cur.val==item:
            #判断是否存在目标
                if cur== self.__head:
                    #如果是头节点,
                    self.__head=cur.next
                    break
                else:
                    #跳过这个节点
                    pre.next=cur.next
                break
            else:
                #二个游标必须相隔一个节点
                pre=cur
                cur=cur.next
    #遍历链表
    def walk(self):
        cur=self.__head
        while cur is not None:
            print(cur.val,end= ' ')
            cur=cur.next

    #查看节点是否存在
    def search(self,item):
        cur=self.__head
        while cur != None:
            if cur.val == item:
                return True
            else:
                #如果不存在就向后移动一位
                cur=cur.next
        return False

if __name__ == '__main__':
    a=Singly_linked_list()
    a.headadd(3)
    a.headadd(4)
    a.tailadd(6)
    a.headadd(7)
    a.middleadd(2,8)
    print(a.search(4))
    a.walk()
    a.remove(7)
    a.walk()

双向链表

理解:双向的,指针头指向尾部,尾部也指向头部

实现方式:(python,与单链表不同的是插入,删除,遍历)

 

 

 

'''
    双链表的实现

'''
#创建结点对象
class Node(object):
    def __init__(self,val):
    #定义节点
        self.val=val
        #前节点
        self.prev=None
        #后节点
        self.next=None


class Double_linked_list(object):
    #数组头节点创建,node=None声明没有元素
    def __init__(self,node=None):
        #__head私有化属性,不被外界访问
        self.__head=node
    #判断是否为空
    def is_empty(self):
        #判断头是否为空
        return self.__head is None

    #查看链表有多少个元素
    def length(self):
        #cur指向头
        cur=self.__head
        #记录有多少元素
        count=0
        #判断链表是否为空
        while cur != None:
            #不是加一
            count+=1
            #指针cur向后移动
            cur=cur.next
        return count

    #头部插入
    def headadd(self,val):
        #构建节点(将插入数值换成结点类型,)
        node=Node(val)
        node.next=self.__head
        self.__head=node
        node.next.prev=node

    #中间插入
    def middleadd(self,pos,val):
        if pos == 0:
            # 当pos=o是就是头部添加
            self.headadd(val)
        elif pos >=self.length()-1:
            # 当 pos大于链表长度就是尾部部添加
            self.tailadd(val)
        else:
            cur=self.__head
            count=0
            while count < pos:
                count+=1
                cur=cur.next
            #退出循环cur指向pos位置
            node=Node(val)
            node.next=cur
            node.prev=cur.prev
            cur.prev.next=node
            cur.prev=node

    #尾部插入
    def tailadd(self,val):
        node = Node(val)
        cur=self.__head
        #如果链表中没有元素
        if cur is None:
            self.__head=node
        else:
            while cur.next is not None:
                cur=cur.next
            cur.next=node
            node.prev=cur


    #删除节点
    def remove(self,item):
        cur=self.__head
        while cur !=None:
        #遍历一遍
            if cur.val==item:
            #判断是否存在目标
                if cur == self.__head:
                    #如果是头节点,
                    self.__head=cur.next
                    if cur.next:
                        #判断链表是否只有一个节点
                        cur.next.prev=None
                    break
                else:
                    #跳过这个节点
                    cur.prev.next=cur.next
                    if cur.next:
                        cur.next.prev=cur.prev
                break
            else:
                #二个游标必须相隔一个节点
                cur=cur.next
    #遍历链表
    def walk(self):
        cur=self.__head
        while cur is not None:
            print(cur.val,end= ' ')
            cur=cur.next

    #查看节点是否存在
    def search(self,item):
        cur=self.__head
        while cur != None:
            if cur.val == item:
                return True
            else:
                #如果不存在就向后移动一位
                cur=cur.next
        return False

if __name__ == '__main__':
    a=Double_linked_list()
    a.tailadd(6)
    a.headadd(7)
    a.headadd(3)
    a.headadd(4)
    a.middleadd(2,8)
    print(a.search(4))
    a.walk()
    a.remove(7)
    a.walk()

 

 

以上是关于算法入门(七,数据结构,单向链表与双链表)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之双链表

C/C++语言数据结构快速入门(代码解析+内容解析)链表(单链表,双链表,循环链表,静态链表)

C/C++语言数据结构快速入门(代码解析+内容解析)链表(单链表,双链表,循环链表,静态链表)

[一周一算法] 链表与插入排序

双向链表与LinkedHashMap

浅谈单链表与双链表的区别