(1)經典型---嫁衣法
無論是寫程式還是幹其他事情,一旦涉及到交換,就總是會遇到第三方。這個第三方可能是公正的監督者,也可能是乙個徒為他人做嫁衣的可憐蟲。在經典法的交換程式中,我們就需要有乙個可憐蟲來為我們提供暫時的服務。程式如下:
void swap(int *a,int *b)
我們看到,我必須用乙個temp變數作為過渡,讓他先擁有然後又再賦值給其他人。可見他也不是徒做嫁衣,而是先索取後奉獻的主人公精神。哈哈,扯遠了。
(2)經典型改進版---范型法
上面的那個swap函式只能交換int型別變數,如果我想交換double型別,short型別,char型別......呢?上面的程式就必須重新寫,可是又不是完全推倒重來,只需要修改相應的型別變數就可以了,如果是用c++來程式設計,我們還可以用到nb的模板,可是c語言就沒有這種特點了。唯一可以用的便是void*指標。void*指標可以視為一種通用指標,任何指標都可以轉換為void*指標而不會丟失值。同理,只要我們把原先的指標變數換成void*型別不就行了。可是,你很快發現,這樣不行。為什麼呢?因為我們沒有通用的嫁衣。c語言中的變數不可以為void型別,也就是說沒有void temp;這種古怪的東西。那怎麼辦呢?我們可以從底層去想兩個數交換的本質。不就是相應的記憶體值交換嘛。我們可以聯想到memcpy函式,我們可以模仿著來,寫乙個函式,通過傳入void*指標和變數型別的位元組大小,來將這兩個變數相應的位元組內容發生對換。程式如下:
void swap(void *a,void *b,size_t size)
}使用的時候可以這樣呼叫:swap( &a,&b,sizeof(int) );
這種位元組的分別交換可以通用各種型別的交換,當然,彼此之間應該是同種型別,否則會因為型別大小,位元組序等一些問題發生錯誤。
(3)取巧型---賦值法
這個方法其實乙個很取巧的方法,大家先看一下程式,看能不能看出巧在**:
void swap(int *a,int *b)
這種方法有乙個好處,那就是不用消耗額外的變數空間,只需要兩個變數做一些運算即可。讓我們慢慢看:
首先:
我用a代表a+b
a=a+b, 這時候a的值為兩者之和
接著,b=a-b,也就是b=a-b=a+b-b=a,這時候b得到了a的值
最後,a=a-b,因為經過上面的運算,b=a,所以a=a-b=a+b-a=b,這時候a得到了b的值。
所以,交換成功了。
(4)詭異型---邏輯運算法
如果沒有仔細拿紙算一算的話,這段程式估計會暈倒很多人,讓我們來看一下吧:
void swap(int *a,int *b)
怎麼樣,夠詭異的吧。如果我們把它拆開來看的話,其實也沒那麼可怕:
首先我們必須明確運算順序,是從右至左:
*a=*a^*b;
*b=*b^*a;
*a=*a^*b;
在解釋這段**的時候,我們先普及一下邏輯運算的基礎知識,^ 符號是異或符號,也就是如果兩個邏輯變數各不相同,其表示式值為1,反之為0 。則有:
a^a=0
a^1=~a
a^0=a
a^b^c=a^(b^c)=b^(a^c)
首先,a=a^b;
接著,b=b^a=b^a^b=a^0=a,這時候b獲得了a的值。
最後,a=a^b=a^b^a=b^0=b,這時候a獲得了b的值。
其實這個方法跟(3)的道理差不多,都是取巧,鑽了賦值的空子。
我就想到這麼多swap函式了,你呢?
你真的會寫週報嗎
初次踏入職場的人而言,寫週報是一件陌生的事情.乙份好的週報對自己的職場有著不可忽視的作用.對於老闆而言,收到乙份的週報,可以盡快了解員工的工作進度以及員工的所遇到的問題,如果有的時候乙份週報什麼問題什麼都沒有,反而會令上級覺的無法把控工作的進度,埋藏著 的炸彈.優秀的週報會令上級覺得此人做事穩重可靠...
幾種swap演算法簡介
記一下幾種swap演算法,以後也方便檢視.最初接觸和使用的一種要屬以下這種了 int x 10 int y 5 int tmp x x y y tmp system.out.println x x y y 這種方法最容易理解,也是最常用的.除了這個,以下的幾種方法覺得有些新鮮 第一種 利用加減法交換...
幾種swap演算法簡介
記一下幾種swap演算法,以後也方便檢視.最初接觸和使用的一種要屬以下這種了 int x 10 int y 5 int tmp tmp x x y y tmp system.out.println x x y y 這種方法最容易理解,也是最常用的.除了這個,以下的幾種方法覺得有些新鮮 第一種 利用加...