2011-11-21 27 views
0

這實際上並不是一個家庭作業問題,只是一個讓我嘮叨我的問題,因爲我在做家庭作業。我的書有時會做一些關於重新排列數據的練習,並且會明確地說通過只更改指針而不是移動數據來完成它(例如,在鏈接列表中使用具有數據字段的「節點」結構和下一個/指針字段,只更改下一個字段)。洗牌數據而不是指針指向它是不好的形式?

反而移動數據是不好的形式嗎?有時似乎更有意義(無論是爲了效率或清晰度)將數據從一個結構移到另一個結構而不是改變指針周圍,我想我只是想知道是否有一個很好的理由來避免這樣做,或者如果教科書正在強制這種限制來更有效地指導我的學習。

感謝您的任何想法。 :)

+0

出於好奇:當你說複製數據比複製指針更有效率時,你想到了什麼樣的例子? – jwd

+0

那麼,在我的一些作業中,我要存儲的唯一數據是int。因此,由於int的大小與指針相同,因此交換兩個ints而不是交換四個指針(比如在一個雙向鏈表中)會更有效率(我知道,我知道,工作量是恆定的,它是如此微不足道效益)。 –

回答

4

這裏有3個原因:

這種通用/可維護性

如果你能得到你的算法只修改指針工作,那麼它將永遠無論你放什麼樣的數據中的工作你的「節點」。

如果您通過修改數據來完成,那麼您的算法將與您的數據結構結合,並且如果您更改數據結構可能無法工作。

效率

另外,你提到的效率,你將很難再找到比複製一個指針,它僅僅是一個整數,通常已經是一個機器字的大小更有效地運作。

安全

而且更進一步,該指針的操作路線不會與它有自己的指針您的數據的其他代碼混淆,因爲@caf指出。

+0

有道理,謝謝。 –

0

移動數據需要更多時間,並且根據數據的性質,它也可能不喜歡重定位(比如包含指向自身的指向任何原因的結構)。

1

這取決於。移動較小的東西通常是有意義的,所以如果被洗牌的數據大於指針(通常是這種情況),那麼洗牌指針而不是數據更有意義。另外,如果其他代碼可能保留了指向數據的指針,那麼它不會期望數據從底部改變,所以這又指向了洗牌指針而不是數據。

+0

這主要是第二個。所有標準的基於節點的容器的迭代器都不會因插入/刪除而失效。重新整理指針只是爲了解決這個問題。 –

1

當複製或移動實際對象很困難或效率低下時,將指針或索引重排。如果更方便的話,對物體本身進行拖拽沒有任何問題。

事實上,通過消除指針,可以消除指針所帶來的大量潛在問題,例如是否以及何時以及如何刪除它們。

0

如果你有指針,我假設它們存在於動態內存中...... 換句話說,它們只是存在......那麼爲什麼麻煩改變數據從一個到另一個,重新分配,如果有必要?

通常,列表的目的是從內存角度將來自任何地方的值存儲到連續列表中。

有了這樣的結構,您可以重新排列和重新排列列表,而無需移動數據。

您必須明白,移動數據意味着讀取和寫入內存(而不是談論重新分配)。

這是資源消耗...所以重新排序只有地址是一個更有效率!

0

這取決於數據。如果你只是在移動int s或char s,那麼洗牌數據不會比指針更昂貴。但是,一旦你達到了一定的規模或複雜程度,你就開始很快失去效率。通過指針移動對象將適用於任何包含的數據,所以習慣使用指針,即使在您的作業中使用的玩具結構上,也可以幫助您在沒有的情況下處理那些大而複雜的對象。

處理類似鏈接列表的東西時,通過指針處理事情特別習慣。鏈表的全部要點是Node部分可以像你喜歡的那樣大或者複雜,並且洗牌,排序,插入或者移除節點的語義都保持不變。這是C++模板容器的關鍵(我知道這不是這個問題的主要目標)。 C++也鼓勵你考慮並限制你用數據混洗東西的次數,因爲這涉及到每次移動時在每個對象上調用複製構造函數。這對許多C++習慣用法來說並不合適,比如RAII,這使得構造函數成本相當高昂,但非常有用。

相關問題