2012-06-12 73 views
1

我想弄清楚如何實現類似冒泡排序但在某些方面有所不同的排序方法。實現類似於冒泡排序的排序方法

的僞代碼會是這樣的:

  1. 獲取列表,並採取第一個元素列表
  2. 如果該元素旁邊是小然後交換元素
  3. 其他標記元素爲移動和重複,直到所有的元素都標

這裏是我想過實施這個問題:

sortElement [] elm= [] 
sortElement [x] elm= [x] 
sortElement [email protected](x:y:xs) elm = 
--first if is to find the element in the list that i want to move 
if elm /=x 
then x:sortElement(y:xs) elm 
else if x > y then y:sortElement(x:xs) elm 
else lis 

stackBubble lis = stackBubble' lis lis 

stackBubble' [] [] = [] 
stackBubble' [x] [] = [x] 
stackBubble' [] [x] = [] 
stackBubble' [email protected](x:xs) [email protected](x1:xs1) = do 

sortElement(stackBubble' lis xs1) x1 

我正的錯誤是在功能stackBubble」

非詳盡模式

如果我不喜歡其他地方建議:

sortElement(x:stackBubble' xs xs1) x1 

我得到一個完全分類列表後一次迭代時,我想得到這樣的事情:

[4,2,7,1] => iterating 4 [2,4,7,1], after iterating all the elements [2,4,1,7]. 

回答

2

解決這個很可能是利用警衛和簡單而又重複的,例如最簡單的方法:

bubble :: Ord a => [a] -> [a] 
bubble (x:y:xs) | x > y = y : bubble (x : xs) 
       | otherwise = x : bubble (y : xs) 
bubble x = x 

你已經把守衛了嗎?以防萬一你沒有,我簡單地解釋一下。對於後衛的語法是

| (expression that evaluates to Bool) = code 

就像在模式匹配哈斯克爾將檢查衛兵自上而下和執行返回true的第一個。 otherwise是剛剛定義爲True的「破案」。

所以通過代碼行會由行:

bubble (x:y:xs) | x > y = y : bubble (x : xs) 

我們的名單分爲X:Y:XS和運行,檢查如果y小於x的第一後衛,如果是y被追加到我們正在構建的結果列表中,並使用(x:xs)再次調用泡沫。

   | otherwise = x : bubble (y : xs) 

第二後衛總是返回True,將x保持在它的位置並再次調用泡泡,並且列表仍然以相同的順序排列。
最後一行僅返回最後一個元素,或者如果您使用空列表調用該函數,則爲空列表。

假設的例子列表[4,2,5,1]的執行將工作是這樣的:

1: 2 is smaller than 4 -> 2 : bubble [4,5,1] 
2: 5 is not smaller than 4 -> 2 : 4 : bubble [5,1] 
3: 1 is smaller than 5 -> 2 : 4 : 1 : bubble [5] 
4: end of list -> 2 : 4 : 1 : 5 -> [2,4,1,5] 

此實現沒有明確的「標記」的作爲移動但這不是必需的元素。

+0

好吧,這是一樣的說:泡'李@(x:y:xs)=如果x> y然後y:泡'(x:xs)其他x:泡(y:xs)。我已經嘗試過這種猜測,因爲在測試之前我沒有在控制檯中重新加載。但是,謝謝你,我想我以後的做法有點矯枉過正。 –

+1

是的。哦,順便說一句,沒有必要做'lis @(x:y:xs)',只要括號中的部分就足夠了。否則,您將整個列表分配給'lis'而不用它。如果您使用-Wall – tazjin

+0

運行它,GHC可以警告您這些事情。感謝您使用-Wall命令,現在就使用它。謝謝你的幫助,這是無價的。 –

2

由於stackBubble'沒有指定結果,當一個參數爲空而另一個具有多個元素時,您會看到錯誤。

+0

是的,你是正確的感謝。在我修復它之後,我的代碼仍然總是返回有序列表,您是否快速看到一些錯誤?我試圖完成的是如果我有一個列表[4,2,5,1],那麼程序會調用sortMe列表和元素進行排序,直到lis1爲空,所以列表[4,2,5,1 ]會變成[2,4,1,5]。感謝您的收穫 –

2

我開始編寫一個更正的版本,但是當我這樣做時,問題得到了回答。我會在這裏包括它反正示範的緣故:

bubbleSort l = 
    bSort l [] 
    where bSort []  acc = acc 
     bSort [x]  acc = acC++ [x] 
     bSort (x:y:xys) acc 
      | x > y  = bSort (acC++ (y:x:xys)) [] 
      | otherwise = bSort (y:xys) (acC++ [x]) 

注意,這可能甚至冒泡排序因爲所有的連接列表的標準極低效(這很可能會是最好追加到累加器列表的頭部,然後在必要時反轉)。這種實現非常幼稚,但相當簡潔,也許很有啓發性,但更多的是因爲它的粗糙性超過了任何積極的美德。

+0

感謝您的代碼。我正在處理一種排序方法,就像冒泡排序但不完全一樣。它起泡每個元素(從元素0開始),例如[3,4,2,1,7]將返回[3,1,2,4,7]。 –