美文网首页
链表--有序链表&无序链表

链表--有序链表&无序链表

作者: 小碧小琳 | 来源:发表于2018-07-07 22:45 被阅读0次

一、无序链表

书中的链表,是由两个类组成的,一个是节点类,一个是链表类。

  • 节点类:节点类又包含初始化, 获得data和next,更改data和next的方法。(一般在编程题中, 只会给初始化,包含data和next属性)
    其中,getNext()就是获得下一个节点,比如
    current = current.getNext()
    的意思,就是current此时被赋值为当前节点的下一个节点
class Node:
    def __init__(self,initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

    def setData(self,newdata):
        self.data = newdata

    def setNext(self,newnext):
        self.next = newnext
  • 列表类:列表类初始化头结点为none,对应的也有几种常用的方法。isEmpty,add,search,size等。

1.1、链表方法---添加节点add

添加节点方法。其中temp是node类的实例。因为无序链表最容易增加新节点的地方是在头部,或者说在了列表的开始。于是我们把新节点作为列表的第一个节点,就可以构建一个链表了。

def add(self,item):
    temp = Node(item)
    temp.setNext(self.head)
    self.head = temp

在add方法中,temp是从节点类Node中得到的一个实例,这个实例有两个属性,一个是data,一个是next。
第二行,类初始化时把temp的data设置为item,next为None。
第三行,实例方法把节点temp的next指向了旧链表的head。
第四行,把链表mylist的头结点设置为当前节点temp。

在下图中可以看到这个步骤,

  • 本来原链表head是节点93(虚线)
  • 新建立一个节点
    节点data为26,next指向None(虚线)
  • 设置新节点temp的next指向head,也就是节点93。
  • 把新节点temp赋值给head。
  • 完成一次添加节点的操作。

################################################################

链表方法--求元素个数(size),查找(search),移除(remove)
这些方法,都是基于一个叫做链表的遍历的操作,

访问完一个节点,将外部引用移动到下一个节点的操作可以简单理解为:

current = current.getNext()
即,将current 赋值为下一个 节点。直到current为None为止。
################################################################

1.2、size方法

  • 建立外部引用,让current为链表头结点,并设置count为0
  • 只要current不为None,就把count加1,然后让当前节点current指向下一节点(循环此步,知道current为None,即不再有节点为止)
def size(self):
    current = self.head
    count = 0
    while current != None:
        count = count + 1
        current = current.getNext()

    return count

1.3、search方法

  • 建立一个外部引用current,并设置一个变量found初始化为False
  • 只要current不为None并且没有找到target(即found==False),就先进行data比对,然后用current = current.getNext()来获得下一个节点。直到循环结束。
def search(self,item):
    current = self.head
    found = False
    while current != None and not found:
        if current.getData() == item:
            found = True
        else:
            current = current.getNext()

    return found

1.4、remove方法

移除一个节点分两步:

  • 1、查找数据,找到要remove的节点
  • 2、是移除节点,并将链表再次链接起来

上述步骤涉及到对节点的操作,需要引入两个外部引用。current和previous。
current代表要被移除的节点,移除以后,将previous节点的next指向下一个节点即可。

previous初始化为None,所以涉及到previous的操作时,要考虑两种情况:1、previous仍然是None ----2、previous是一般的节点

在此处代码中,也就是,当第一步完成found=True时,要对previous进行判断,根据情况更改指针。

此处我们假设,一定能找到要删除的节点,因此只用bool来控制循环就行了。

def remove(self,item):
    current = self.head
    previous = None
    found = False
    while not found:
        if current.getData() == item:
            found = True
            #当找到需要移除的节点时,才进行移除操作
            if previous == None:
                self.head = current.getNext()
            else:
                previous.setNext(current.getNext())
        else:
            previous = current
            current = current.getNext()

二、有序链表

相对于无序链表,有序链表仍然有add,remove,search等类方法。
在实现上,size,remove的方法操作是一样的,但是因为有序,add,search的方法就要有些许改变了。

同样,此时我们有两个类,一个节点类Node,跟上面的一样,一个有序链表类

class OrderedList:
    def __init__(self):
        self.head = None

2.1 、search方法

因为有序,所以我们不需要一下搜索到底了,因此,当我们搜索到一个节点发现data比target要大时,还没有搜索到target,那我们就可以结束搜索了。所以,相对于无序链表的search方法, 我们额外加了一个stop变量,来控制循环。

  • 找到了target,就把found变为True。
  • 发现了一个data比target大,没找到target,把stop变为True
  • 没找到target,data比target小,就接着向右搜索
def search(self,item):
    current = self.head
    found = False
    stop = False
    while current != None and not found and not stop:
        if current.getData() == item:
            found = True
        else:
            if current.getData() > item:
                stop = True
            else:
                current = current.getNext()

    return found

2.2 、add方法

不同于无序链表,只需要在头部添加新节点就行了。要考虑添加节点以后链表仍是有序的。
分为两步

  • 第一步,找到需要添加节点的位置。
    为此也增加一个控制循环的变量stop。找到新节点位置的两种情况:
    1、当找到data大于target的节点时,stop变为True,此时执行添加节点的操作。
    2、当循环遍历完整个链表是,停止循环,添加节点。

  • 第二步,根据位置,添加节点。
    又因为在链表内部进行增加节点的操作,所以也需要两个外部引用变量previous和current。
    另外,previous同样需要有两种情况需要考虑。

def add(self,item):
    #设置外部引用, 用于节点操作
    current = self.head
    previous = None
    #设置stop变量用于控制循环
    stop = False
    while current != None and not stop:
        if current.getData() > item:
            stop = True
        else:
            previous = current
            current = current.getNext()
    #循环结束,第一步完成,找到了需要添加节点的位置
    #第二步,添加节点,位置不同,操作也不同,分为头结点,中间节点
    temp = Node(item)
    if previous == None:
        temp.setNext(self.head)
        self.head = temp
    else:
        temp.setNext(current)
        previous.setNext(temp)

相关文章

  • 链表--有序链表&无序链表

    一、无序链表 书中的链表,是由两个类组成的,一个是节点类,一个是链表类。 节点类:节点类又包含初始化, 获得dat...

  • 文章列表

    基本数据结构 栈 队列 双端队列 无序链表 有序链表 递归 递归 搜索与排序 搜索

  • 数据结构 04 链表

    链表 无序链表: 每个节点的入口都是链头.有序链表: 每个节点的入口是根据已有节点比较, 存放在大于和小于值的...

  • leetcode 链表 [C语言]

    21. 合并两个有序链表 合并两个有序链表 61. 旋转链表 (快慢指针) 61. 旋转链表 相关标签 : 链表 ...

  • 算法 - 链表实现(OC) 及简单的链表算法

    链表实现 打印链表 链表反转 (使用递归法) 两个有序链表合并为一个有序链表 力扣题[https://leetco...

  • 二分查找

    顺序查找(基于无序链表) 基于有序数组 完美散花,谢谢。

  • 链表

    链表 单链表反转链表中环的检测两个有序链表合并删除链表倒数第n个节点求链表的元素总个数 一.单向链表 链表共有特征...

  • leecode刷题(23)-- 合并两个有序链表

    leecode刷题(23)-- 合并两个有序链表 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回。新...

  • 线性表练习题

    初始设置 1. 题目1 将2个递增的有序链表合并为⼀个链表的有序链表。 要求: 结果链表仍然使⽤两个链表的存储空间...

  • 数据结构与算法-线性表练习题

    初始设置 1. 题目1 将2个递增的有序链表合并为⼀个链表的有序链表。 要求: 结果链表仍然使⽤两个链表的存储空间...

网友评论

      本文标题:链表--有序链表&无序链表

      本文链接:https://www.haomeiwen.com/subject/ecaguftx.html