メモリ
-
コンピュータの役割
- ストレージとコンピューティングバイナリデータ。
-
どのようにコンピュータ1 + 1 =?オペレーティング
- 1コンピュータのメモリにロードされ、次いでコンピュータベースレジスタを追加します追加するためのメモリに格納されたデータを指定します。
- いいえ減算レジスタ、+( - 1)がありません-1。
-
変数の概念
- 自然が言えば、変数は、コンピュータ上のメモリ空間の一部を指します。
- 2つのメモリ空間固有の特性があります。
- 住所:進数表現
- 役割:便利なCPUアドレッシング。ハウス番号。
- サイズ:ビット、バイト、KB、MB、GB、TB
- これはメモリブロックに格納された値の範囲を決定します
- 住所:進数表現
-
A =そのメモリ10(基準点)を理解
- 引用:変数であります一般的に言えば、可変表示/保存は、メモリ空間のメモリアドレス空間の一部です。
- ポイント:可変基準ストレージ/メモリ・ブロックは、可変メモリブロックへのアドレス空間、または参照を表している場合。
- 例:オブジェクトに対応する学生のメモリ空間へのSTU =学生()、STUポイント
- 次=ノード()、next.item、next.next
-
同じデータ型のオープンスペース固有のメモリサイズに
- データ整形:4バイト
- フロート:4,8byte
- 文字:1バイト
個人的な理解
-
以下のために永続ストレージコーディングテーブル格納によれば、のために:
ascii
:1ワード - > 1つのバイトgbk
:1ワード - > 2つのバイトutf-8
:1ワード - > 1-4バイト(またはヨーロッパ、アジアで2つのバイトに含まれている生のASCIIバイト、3バイト)
-
以下のためにPythonのメモリ空間以下の場合:
-
各変数代入のデータ型は、スペースを予約し、異なる変数の異なりますデータ自体のサイズが予約領域のサイズには影響しませんしながら、データ型は、データのみのために確保されたメモリ領域のサイズを決定します
-
メモリは、予約された領域よりも後に拡張することができますこうしたカスタム予約メモリ空間のおおよそのサイズはわずか資源の無駄ですが、、しかし、異なるサイズの各要素のための予備スペースへのコンピューティングリソースのCPUを保存そして限り、可変ポイントが変化するだけでなく、非常にCPU効率が占有されている予備空間を、再計算したように、データメモリ空間のサイズに従って計算場合
-
Pythonの予備スペース:
-
シェーピング:4バイト。
-
1byte = 8bits
、1ビットは、2進数を記憶することができますそして、1つのバイトが8ビットの2進数を記憶することができる、すなわち、記憶されてもよい2**8
進数(0〜255)(256) -
同様に、4つのバイトを格納することができる
2**32
種子の10進数np.iinfo('int8') # int,相较于无符号,需要浪费第一位用来储存+-号,2**7=128,所以范围就是 -127~127
iinfo(min=-128, max=127, dtype=int8)
[6]:
np.iinfo('uint8') # 无符号int,2**8=256,范围就是0-255
iinfo(min=0, max=255, dtype=uint8)
-
-
フロート:4/8バイト(単精度/倍精度)。
-
STR:1つの1バイト文字が、すべての文字列が最終を持って
-0
、彼は余分に1バイトを持っています(「こんにちは」は、例えば- > 6バイト)
-
-
受注テーブル
分類
-
データ構造要素が順次に格納されて、シーケンステーブル構造は、二つの形態に分けることができます。
- Singleデータ型(配列)と複数の種類のデータ(リスト)。
-
Pythonでリストとタプルは、複数のデータ・タイプオーダーテーブルに属しています
-
図配列テーブルメモリの単一のデータタイプ(アレイ)(オープンRAM連続)
- オフセットが固定されているように、配列データ・タイプは、統一されています
- これは、インデックスの起源を説明するかもしれません
-
複数のデータ型図のシーケンス・テーブル・メモリ(RAM不連続オープン)
- リストは大きく異なるが、オフセットが、我々はインデックスリスト(同じオフセット)のメモリアドレスによって保存されたを達成することができ、異なるデータ型に格納することができます
個人的な理解の上図:
-
受注テーブルカテゴリ:
- 単一のデータストレージ構造、複数のデータストレージ構造
-
配列:単一のデータ・ストレージ・構造
- これは、配列の要素自体に保存されています
- 配列データ型の中で統一する必要があります。シフト量算出を容易にするために
-
リスト:複数のデータ記憶構造
- リストには、メモリアドレスに格納されました!!!
- 要素のリストを直接リストに格納されていない、それらは非連続の記憶の形式でメモリに格納され、ポイントのリストだけでありさ 各要素のメモリアドレスを格納します 注文したコンテナは、また、このような理由のために、リストは、異なるデータ型に格納することができますが、インデックスは変わりません
-
注文テーブル欠点:、挿入位置の後に変更するすべての要素のインデックス、高い時間複雑度データを挿入
-
一覧短所:低クエリ効率を見つけなければなりません
短所:
- 構造は、連続的なストレージ容量を適用するには、事前にオーダー表のデータサイズを知る必要があります
- 連続した収納スペースとは何ですか?
- 私が検索したいので、自由があり、内部メモリ、未使用の順に1つのダウンずつ、それが誰であるかを見るためには、これは、断片化された場合には、多くのスペースを使用することをスズメバチの巣につながるときです継続的、かつ十分大きなメモリ空間それは、効率を遅らせる可能性があります
- 連続した収納スペースとは何ですか?
- そして、条件に合うように再配置するデータニーズを拡大するだけでなく、スペースを見つけるために時間とメモリ空間があります
リスト
- 一覧(リンクリスト)は、共通の基本的なデータ構造、リニアテーブル、シーケンステーブルとしてではなく継続的に保存されていないデータであるが、次のノードの情報に格納された各ノード(データ記憶手段)(即ち、アドレス)
利点:
- 注文表は、各ノードリンクリストがに関して不連続であることができ、それが連鎖検索で達成することができ、各ノードに格納された次のノードのメモリアドレスによって提供されるコンピュータのメモリ空間の利点を取ることができ、継続的に保存された必要はありません。これは、柔軟な動的なメモリ管理を可能にします
- 拡張メモリアドレスが最後のノード限り、新しいノード上に保存することができませんデータ移動
私たちは、リストのメソッドを実装する必要があります。
- .is_empty():リストは空です
- .LENGTH():鎖長
- .TRAVEL():トラバースリスト全体
- .add(アイテム):リスト要素のヘッドを追加します
- .append(アイテム):要素を追加するには、リストの末尾
- .insert(POS、項目):追加要素を指定された場所
- .remove(アイテム):ノードの削除
- (項目).search:ノードのルックが存在
ノード
# 节点的封装
class Node(object):
def __init__(self,item):
self.item = item
self.next = None
リスト
class Link(object):
"""可以发现链表的各种方法中如果涉及第一个节点都要额外定义,因为第一个节点连接的是self._head"""
def __init__(self):
self._head = None
def is_empty(self):
return self._head == None
def add(self,item):
"""三步走,实例化节点,新节点连上一个节点,self._head连新节点"""
node = Node(item)
node.next = self._head
self._head = node # 将_head指向当前节点
def append(self,item):
node = Node(item)
# 如果链表为空
if not self._head:
self._head = node
return
cur = self._head
pre = None # 用来存储cur的上一个节点,因为while循环最后会找到None为止,到时候再找上一个对象就麻烦了,所以我们手动存储
while cur:
pre = cur
cur = cur.next
pre.next = node # 当while循环结束的时候,pre就指向了链表中最后一个节点,而不是None
def travel(self):
# cur指向了第一个节点
# _head要永远指向第一个节点,轻易不要修改_head的指向,不然可能会导致数据丢失,
# 因为你每个节点就只存储了下一个点的内存地址,一个点断了,后面的数据就都找不到了
cur = self._head
while cur:
print(cur.item)
cur = cur.next
def length(self):
count = 0
cur = self._head
while cur:
count += 1
cur = cur.next
return count
def search(self,item):
"""查找item对应的节点是否存在,返回Bool"""
cur = self._head
while cur:
if cur.item == item:
return True
cur = cur.next
return False
def insert(self,pos,item):
"""
插入操作核心在于pre跟cur代表两个连续的节点,根据索引进行循环得到pre跟cur后,
pre.next连接node,node.next连接cur
"""
node = Node(item)
if pos == 0: # 插入首位需要调整self._head值
node.next = self._head
self._head = node
return
# 在非首位插入元素
cur = self._head
pre = None
for i in range(pos):
pre = cur
cur = cur.next
pre.next = node
node.next = cur
def remove(self,item):
"""删除核心在于,并没有进行删除操作,只是将要删除节点的前后节点直接进行连接,跳过该节点"""
if self._head.item == item:
self._head = self._head.next
pre = None
cur = self._head
while cur.next: # 这里为了避免循环内cur.next得到的是None,下面的cur.item会报错,'NoneType' object has no attribute 'item'
pre = cur
cur = cur.next
if cur.item == item:
pre.next = cur.next
return
使用します。
link = Link()
#link.add(1)
#link.add(3)
#link.add(2) # 2,3,1
link.append(4)
link.append(6)
link.append(5) # 2,3,1,4,6,5
link.travel()
print(link.search(1))
4
6
5
False
インサート
link = Link()
link.append(4)
link.append(5)
link.append(6)
link.insert(0,7) # 插哪个位置都可以
link.travel()
7
4
5
6
削除する
link = Link()
link.append(4)
link.append(5)
link.append(6)
link.remove(5) # 插哪个位置都可以
link.travel()
4
6
インタビューの質問:
- 自分のリストを達成フリップ
- 1,2,3,4,5
- フリップ提供:5,4,3,2,1
- 要件:ポイントはリストの反転出力を達成するためにノードを修正します!
コード:
# 节点的封装
class Node(object):
def __init__(self,item):
self.item = item
self.next = None
class Link(object):
def __init__(self):
self._head = None
def is_empty(self):
return self._head == None
def add(self,item):
"""三步走,实例化节点,新节点连上一个节点,self._head连新节点"""
node = Node(item)
node.next = self._head
self._head = node # 将_head指向当前节点
def append(self,item):
node = Node(item)
# 如果链表为空
if not self._head:
self._head = node
return
cur = self._head
pre = None # 用来存储cur的上一个节点,因为while循环最后会找到None为止,到时候再找上一个对象就麻烦了,所以我们手动存储
while cur:
pre = cur
cur = cur.next
pre.next = node # 当while循环结束的时候,pre就指向了链表中最后一个节点,而不是None
def travel(self):
# cur指向了第一个节点
# _head要永远指向第一个节点,轻易不要修改_head的指向,不然可能会导致数据丢失,
# 因为你每个节点就只存储了下一个点的内存地址,一个点断了,后面的数据就都找不到了
cur = self._head
while cur:
print(cur.item)
cur = cur.next
def length(self):
count = 0
cur = self._head
while cur:
count += 1
cur = cur.next
return count
def search(self,item):
"""查找item对应的节点是否存在,返回Bool"""
cur = self._head
while cur:
if cur.item == item:
return True
cur = cur.next
return False
def insert(self,pos,item):
"""
插入操作核心在于pre跟cur代表两个连续的节点,根据索引进行循环得到pre跟cur后,
pre.next连接node,node.next连接cur
"""
node = Node(item)
if pos == 0: # 插入首位需要调整self._head值
node.next = self._head
self._head = node
return
# 在非首位插入元素
cur = self._head
pre = None
for i in range(pos):
pre = cur
cur = cur.next
pre.next = node
node.next = cur
def remove(self,item):
"""删除核心在于,并没有进行删除操作,只是将要删除节点的前后节点直接进行连接,跳过该节点"""
if self._head.item == item:
self._head = self._head.next
pre = None
cur = self._head
while cur.next: # 这里为了避免循环内cur.next得到的是None,下面的cur.item会报错,'NoneType' object has no attribute 'item'
pre = cur
cur = cur.next
if cur.item == item:
pre.next = cur.next
return
def reverse(self):
"""实现链表的反转"""
cur = self._head
pre = None
while cur:
storage = cur.next # 先把下一个节点存起来,不然数据周转不开
cur.next = pre # 下一个节点的next指向上一个节点
pre = cur # 老操作了
cur = storage # cur往前推进
self._head = pre
使用します。
li = Link()
items = [1,2,3,4,5]
for item in items:
li.append(item)
li.travel()
li.reverse()
print('-')
li.travel()
結果:
1
2
3
4
5
-
5
4
3
2
1