Pythonのインタビューテストサイトは、多くの場合、素人の操作をリスト

Pythonのインタビューテストサイトは、多くの場合、素人の操作をリスト

インタビューPythonの開発では、我々は多くの場合、リストの操作に関する質問に遭遇します。一つは、非常に古典的順不同リスト構造としてリストデータ構造をリンクするだけでなく、開発エンジニアは、習得しなければなりません。この記事では、私はいくつかの共通の構造リスト自体の動作データの機能だけでなく、あなたに簡単な言葉で説明するのリストが表示されます、私はこの記事の読者はリストの操作を習得することができます願っています。

1.リストとは何ですか?

簡単に言えば、リストは順不同リストです。あなたは、ランダムな配列としてリンクリストデータ内に置くことができ、かつ要素の間には一定の順序がありません。それが故障しているので、そう、私たちが来て、以下に示すように、内部のインデックス位置と操作要素と一緒に行くように簡単にターゲットリストのように動作することはできません。

IMG図1

したがって、このような状況は、どのように我々はそれの内部の様々な要素を見つけることができますか?

実際には、実際にはノードノードのオブジェクトと呼ばれるリストの各要素に、ノードは、それぞれ2つのメッセージを保持する、一つは、このノードの値の値であり、他方が次の参照に対応するノードの次のノードです。このように、実際には、ノードとノードとの間にチェーンのように、名前リストの原点である、相互に関連する、鎖構造を形成します。このような連鎖構造で、ちょうど私達に出発点を与える、我々はノードの出発点に沿ってすべてのノードにノードを見つけることができるようになります、このリストには、全体のデータ構造の中核です。

2.どのようにリンクリストを実装するには?

すでに述べたように、キーリスト構造を使用すると、リストの前に達成したいので、我々はノードノードオブジェクトを定義する必要があり、ノードノードオブジェクトです。データは、現在のノードの値は、次のノードへの次の現在のノードを参照して各ノードに格納されているので、我々は、Nodeオブジェクトを定義している可能性が:

class Node:

    def __init__(self, data):
        self.data = data    # 保存当前节点的值
        self.next = None    # 保存当前节点中下一个节点的引用

次のように内部の情報ノードを取得および設定することができるように、我々は、いくつかのメソッドを定義する必要があります。

def __init__(self, data):
        self.data = data
        self.next = None
    
    # 获取node里面的数据
    def getData(self):
        return self.data
    
    # 获取下一个节点的引用
    def getNext(self):
        return self.next
    
    # 设置node里面的数据
    def setData(self, newdata):
        self.data = newdata
    
    # 设置下一个节点的引用
    def setNext(self, newnext):
        self.next = newnext

内部リスト構造での使用に便利なノード内のデータにアクセスするためのこれらのメソッド。

良いNodeオブジェクトの定義の後、我々は、オブジェクトのリストを定義するために始めることができます。ここでは片方向リンクリストの話をしているので、英語がシングルリンクリストになりました。あなたがリストを定義すると、最も顕著なヘッド(頭)は、我々が前に言ったように、私たちは頭に沿って他のすべてのノードを見つけることができるようになります、リストの先頭を見つけ、リストを定義しました。次のようにそのため、最初の定義リストは、私たちが頭を定義する属性限り、非常に簡単です:

class MySingleLinkList():
    

    def __init__(self):

        # 定义链表的头结点

        self.head = None

ここでは、それが最初のノードの参照(self.head)の唯一のリンク構造を含むリストオブジェクト自体は逆に、任意のノードNodeオブジェクトが含まれていないことに注意してください、実際には、それは常にリストの先頭を指すようになります最初のノード。あなたはNoneに向かう場合は、実際には、これは空のリストであることを意味します。定義により、独立したオブジェクトやNodeオブジェクトリストLINKLISTは、お互いが含まれていません。基本的な考え方は、限り、私たちはこの基本原理を覚えているように、我々は、実装の他の方法に続いて、リストを開始することができ、非常に重要です。

IMG図2

一般的には、リンクリストの基本的な動作は以下に主に含まれている必要があります:

  • それは)リストが空のisEmpty(かどうかを判断します
def isEmpty(self):
    '''
    判断head指向的节点是否为None,如果head指向None,说明该链表为空
    '''
    return self.head == None
  • リストのサイズの長さを取得します()

リストのキーの長さは、リンクリストをトラバースし、ノード数をカウントするために取得することです。リスト内の移動頻繁にリスト操作の基本的な操作に使用される、このような問合せリストノードとして、操作はリストを横断関与します削除します。私たちは、リストの先頭には、各ノードの次を見つけるようになったから、次なしに、最終的な一つのノードまで、それが完成を通過することを意味し、リストを横断するとき、我々は最初のリストのヘッドノードを見つけなければならない、前に言ってきました。

def size(self):
    current = self.head  # 将链表的头节点赋值给current,代表当前节点
    count = 0
    while current != None:
        count += 1
        current = current.getNext()  # 计数后,不断把下一个节点的引用赋值给当前节点,这样我们就能不断向后面的节点移动
    return count
  • )(リンクリストのノードの追加に向かって増加

リストにノードを追加し、我々は二つの質問を考慮する必要があります。最初の質問は、どこに新しいノードが追加されていますか?あなたは、新しいノード自体は問題ではありませんリストに追加され、実際には順序なしリスト構造、である、考えることができます。操作の我々のコードの難易度が異なるためではなく、リスト内の別の位置に追加します。私たちはこのような観点からして、最初のノードへの参照を保持以前は常に定義されたリスト構造は、最も簡単な方法は、新しいノードが最初のリストになるためになるように、リストの先頭に新しいノードを追加することであるためノードおよび後方順番に前のノード。第二の問題は、アクションを必要とするために、新しいノードを追加するとき、ということでしょうか?実際には、新しいノードを追加するためには、2つの手順が必要です。まず、新しいノードの先頭の前に次のノードに割り当てる必要性は、新しいノードが次され、その後、ヘッドノードに新しいノードを割り当て、それが新たなヘッド(図3)となります。

IMG図3

def add(self, val):
    temp = Node(val)
    temp.next = self.head   # 将原来的开始节点设置为新开始节点的下一节点
    self.head = temp        # 将新加入节点设置为现在的第一个节点

必须要注意temp.next = self.head和self.head=temp这两个语句的先后顺序,如果把self.head=temp写在前面,则会使得head原来指向的下一个节点的信息全部丢失,这并不是我们想要的结果(如图4所示)。

IMG图4

  • 查找指定节点是否在链表中 search()

要实现查找算法,必然也是要遍历链表的,我们可以设置一个布尔变量作为是否查找到目标元素的标志,然后通过遍历链表中的每个元素,判断该元素的值是否等于要查找的值,如果是,则将布尔值设置为True,最后返回该布尔值即可。代码如下:

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
  • 移除指定节点 remove()

移除指定节点也是在链表中一个常见的操作,在移除指定节点时,除了要先遍历链表找到指定元素外,还需要对这个即将被移除的节点做一些处理,以确保剩下的节点能够正常工作。在我们找到要被移除的节点时,按照之前写过的遍历方法我们知道,current应该是指向要被移除的节点。可问题是怎么才能移除掉该节点呢?为了能够移除节点,我们需要修改上一个节点中的链接,以便使其直接指向当前将被移除节点的下一个节点,使没有任何其他节点指向这个被移除的节点,以达到移除节点的目的。但这里有个问题,就是当我们循环链表到当前节点时,没法回退回去操作当前节点的前一个节点。所以,为了解决这个问题,在遍历链表时,除了需要记录当前指向的节点current外,还需要设置一个变量来记录当前节点的上一个节点previous,每次循环时,如果当前节点不是要被移除的节点,那么就将当前节点的值赋值给previous,而将下一个节点的引用赋值给当前节点,以达到向前移动的目的。同时,在找到了将被移除的节点后,我们会把found设置为true,停止遍历。

另外,在删除节点时,可能会有三种情况:

(1)削除されたノードは、リンクリストで始まるノードで、前の値はNoneにしなければならない、我々は唯一に向かうcurrent.nextを割り当てる必要があります。
(2)除去されたノードは、リスト内の最後のノードです。
(3)ノードが除去される(すなわち、第1のNOR最後のノードではない)一般的なノードです。
前記(2)(3)特別な処理ケースを必要としない、次の現在の前に直接隣接して配置。

def remove(self, item):
    current = self.head
    previous = None
    found = False
    
    # 判断指定值是否存在于链表中 
    if not self.search(item):
        return
        
    while not found:
        if current.getData() == item:
            found = True
        else:
            previous = current
            current = current.getNext()
        
    if previous == None:
        self.head = current.getNext()
    else:
        previous.setNext(current.getNext())
  • getAllData(リスト内のすべてのノードの値を取得します)

私たちは、リストのまさに価値のトラックを保つために、リンクされたリスト内のすべてのノードの値を取得します。リストは、リストを見るために直接プリントアウトすることができるほど一般的ではないので、一般的に、我々はリストを取得するために、リストに取り出しリンクされたリスト内の各ノードの値によってリストをトラバースし、リストを印刷する必要があるためすべてのノード値の目的。

def getAllData(self):    # 得到链表中所有的值
    data = []
    current = self.head
    while current:
        data.append(current.getData())
        current = current.getNext()
    return data

これらは、操作の私たちの通常の方法であり、対応するコードはリストで実装され、その後、我々は我々が書いたものを操作しようとすると、これらのメソッドは、右テストすることができます。

linkList = MySingleLinkList()
for i in range(10, 50, 5):
    linkList.add(i)
print(linkList.size())  # output: 8
print(linkList.getAllData()) # output: [45, 40, 35, 30, 25, 20, 15, 10]

linkList.remove(25)
print(linkList.getAllData()) # output: [45, 40, 35, 30, 20, 15, 10]

linkList.search(25)  # output: False
linkList.isEmpyt()   # output: False

これらの定義されたPythonのアルゴリズム私たちはしばしばインタビューで、共通の操作のリストに遭遇します

おすすめ

転載: www.cnblogs.com/TMesh-python/p/11731480.html