西門子SCL編程_排序算法
項目上需要,因此研究了一下排序
參考1:北島李工 西門子SCL語言編程實例——冒泡排序
參考2:《漫畫算法:小灰的算法之旅》
參考3:雞尾酒排序優化版
參考4:西門子array數據類型_西門子SCL編程入門教程連載(16)-Variant相關指令
參考5:西門子SCL博途中如何讀取泛型數組——任意長度的最大值及索引
參考6:Variant類型
參考7:SCL高級語言編寫如何開啟運行時間最少的幾台設備
參考8:TIA protal與SCL從入門到精通(5)——函數終止跳轉處理
參考9:博圖SCL_遞歸算法的應用
參考10:李工談工控
冒泡排序
FUNCTION "bubbleSort" : Void
TITLE = bubble sort
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : bootloader
VERSION : 0.1
//冒泡排序,使用雙循環進行排序。外部循環控制所有的回合,內部循環實現每一輪的冒泡處理,先進行元素比較,再進行元素交換。
VAR_INPUT
mode : Bool; // 0升序、1降序
END_VAR
VAR_IN_OUT
arraySort : Array[*] of Int;
END_VAR
VAR_TEMP
lowBound : DInt; // 數組下限
upBound : DInt; // 數組上限
i : Int; // 循環變量i
j : Int; // 循環變量j
tmpInt : Int; // 臨時變量int
END_VAR
BEGIN
//冒泡排序,使用雙循環進行排序。外部循環控制所有的回合,內部循環實現每一輪的冒泡處理,先進行元素比較,再進行元素交換。
//作者:bootloader
//2022年3月25日 11:30 周五
//獲取數組上限
#upBound := UPPER_BOUND(ARR := #arraySort, DIM := 1);
//獲取數組下限
#lowBound := LOWER_BOUND(ARR := #arraySort, DIM := 1);
FOR #i := #lowBound TO #upBound DO
FOR #j := #lowBound TO #upBound - #i DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] > #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
END_IF;
ELSE
//降序
IF #arraySort[#j] < #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
END_IF;
END_IF;
;
END_FOR;
END_FOR;
END_FUNCTION
冒泡排序Upd1
FUNCTION "bubbleSort_Upd1" : Void
TITLE = bubble sort
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : bootloader
VERSION : 0.1
//冒泡排序第2版
VAR_INPUT
mode : Bool; // 0升序、1降序
END_VAR
VAR_IN_OUT
arraySort : Array[*] of Int;
END_VAR
VAR_TEMP
lowBound : DInt; // 數組下限
upBound : DInt; // 數組上限
i : Int; // 循環變量i
j : Int; // 循環變量j
tmpInt : Int; // 臨時變量int
isSorted : Bool; // 有序標記
END_VAR
BEGIN
//冒泡排序,使用雙循環進行排序。外部循環控制所有的回合,內部循環實現每一輪的冒泡處理,先進行元素比較,再進行元素交換。
//如果在本輪排序中,元素有交換,則說明數列無序;如果沒有元素交換,則說明數列已然有序,然后直接跳出大循環。
//作者:bootloader
//2022年3月26日 15:12 周六
//獲取數組上限
#upBound := UPPER_BOUND(ARR := #arraySort, DIM := 1);
//獲取數組下限
#lowBound := LOWER_BOUND(ARR := #arraySort, DIM := 1);
FOR #i := #lowBound TO #upBound DO
#isSorted := TRUE; //有序標記,每一輪的初始值都是true
FOR #j := #lowBound TO #upBound - #i DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] > #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
//因為有元素進行交換,所以不是有序的,標記為false
#isSorted := FALSE;
END_IF;
ELSE
//降序
IF #arraySort[#j] < #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
//因為有元素進行交換,所以不是有序的,標記為false
#isSorted := FALSE;
END_IF;
END_IF;
END_FOR;
IF #isSorted THEN
RETURN;
END_IF;
END_FOR;
END_FUNCTION
冒泡排序Upd2
FUNCTION "bubbleSort_Upd2" : Void
TITLE = bubble sort
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : bootloader
VERSION : 0.1
//冒泡排序第3版
VAR_INPUT
mode : Bool; // 0升序、1降序
END_VAR
VAR_IN_OUT
arraySort : Array[*] of Int;
END_VAR
VAR_TEMP
lowBound : DInt; // 數組下限
upBound : DInt; // 數組上限
i : Int; // 循環變量i
j : Int; // 循環變量j
tmpInt : Int; // 臨時變量int
isSorted : Bool; // 有序標記
lastExchangeIndex : Int; // 最后一次交換的位置
sortBorder : DInt; // 無序數列的邊界
END_VAR
BEGIN
//冒泡排序,使用雙循環進行排序。外部循環控制所有的回合,內部循環實現每一輪的冒泡處理,先進行元素比較,再進行元素交換。
//如果在本輪排序中,元素有交換,則說明數列無序;如果沒有元素交換,則說明數列已然有序,然后直接跳出大循環。
//使用lastExchangeIndex記錄最后一次交換的位置,sortBorde記錄無序數列的邊界
//作者:bootloader
//2022年3月26日 18:27 周六
//獲取數組上限
#upBound := UPPER_BOUND(ARR := #arraySort, DIM := 1);
//獲取數組下限
#lowBound := LOWER_BOUND(ARR := #arraySort, DIM := 1);
//--記錄最后一次交換的位置--
#lastExchangeIndex := 0;
//--無序數列的邊界,每次比較只需要比到這里為止--
#sortBorder := #upBound; //數組curVT_tmp中最大下標30
FOR #i := #lowBound TO #upBound DO
#isSorted := TRUE; //有序標記,每一輪的初始值都是true
FOR #j := #lowBound TO #sortBorder - 1 DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] > #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
//因為有元素進行交換,所以不是有序的,標記為false
#isSorted := FALSE;
//更新為最后一次交換元素的位置
#lastExchangeIndex := #j;
END_IF;
ELSE
//降序
IF #arraySort[#j] < #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
//因為有元素進行交換,所以不是有序的,標記為false
#isSorted := FALSE;
//更新為最后一次交換元素的位置
#lastExchangeIndex := #j;
END_IF;
END_IF;
END_FOR;
#sortBorder := #lastExchangeIndex;
IF #isSorted THEN
RETURN;
END_IF;
END_FOR;
END_FUNCTION
雞尾酒排序
FUNCTION "CocktailOrdering" : Void
TITLE = Cocktail ordering
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : bootloader
VERSION : 0.1
//雞尾酒排序
VAR_INPUT
mode : Bool; // 0升序、1降序
END_VAR
VAR_IN_OUT
arraySort : Array[*] of Int;
END_VAR
VAR_TEMP
lowBound : DInt; // 數組下限
upBound : DInt; // 數組上限
i : Int; // 循環變量i
j : Int; // 循環變量j
tmpInt : Int; // 臨時變量int
isSorted : Bool; // 有序標記
END_VAR
BEGIN
//雞尾酒排序又稱雙向冒泡排序、雞尾酒攪拌排序、攪拌排序、漣漪排序、來回排序或快樂小時排序, 是冒泡排序的一種變形。該算法與冒泡排序的不同處在於排序時是以雙向在序列中進行排序。
//作者:bootloader
//2022年3月27日 02:08 周日
//獲取數組上限
#upBound := UPPER_BOUND(ARR := #arraySort, DIM := 1);
//獲取數組下限
#lowBound := LOWER_BOUND(ARR := #arraySort, DIM := 1);
FOR #i := #lowBound TO #upBound / 2 DO //數組長度的一半
//有序標記,每一輪的初始值都是true
#isSorted := TRUE;
//奇數輪,從左向右比較和交換
FOR #j := #i TO #upBound - #i DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] > #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
//有元素交換,所以不是有序的,標記為false
#isSorted := FALSE;
END_IF;
ELSE
//升序
IF #arraySort[#j] < #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
//有元素交換,所以不是有序的,標記為false
#isSorted := FALSE;
END_IF;
END_IF;
END_FOR;
IF #isSorted THEN
RETURN;
END_IF;
//在偶數輪之前,將#isSorted重新標記為true
#isSorted := TRUE;
//偶數輪,從右向做比較和交換
FOR #j := (#upBound - #i) TO (#i + 1) BY -1 DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] < #arraySort[#j - 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j - 1];
#arraySort[#j - 1] := #tmpInt;
//有元素交換,所以不是有序的,標記為false
#isSorted := FALSE;
END_IF;
ELSE
//降序
IF #arraySort[#j] > #arraySort[#j - 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j - 1];
#arraySort[#j - 1] := #tmpInt;
//有元素交換,所以不是有序的,標記為false
#isSorted := FALSE;
END_IF;
END_IF;
END_FOR;
IF #isSorted THEN
RETURN;
END_IF;
END_FOR;
END_FUNCTION
雞尾酒排序Upd1
FUNCTION "CocktailOrdering_Upd1" : Void
TITLE = Cocktail ordering
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : bootloader
VERSION : 0.1
//雞尾酒排序改進版
VAR_INPUT
mode : Bool; // 0升序、1降序
END_VAR
VAR_IN_OUT
arraySort : Array[*] of Int;
END_VAR
VAR_TEMP
lowBound : DInt; // 數組下限
upBound : DInt; // 數組上限
i : Int; // 循環變量i
j : Int; // 循環變量j
tmpInt : Int; // 臨時變量int
isSorted : Bool; // 有序標記
lastRightExchangeIndex : Int; // 最后一次交換的位置
lastLeftExchangeIndex : Int; // 最后一次交換的位置
rightUnsortBorder : DInt; // 無序數列的邊界
leftUnsortBorder : DInt; // 無序數列的邊界
END_VAR
BEGIN
//雞尾酒排序又稱雙向冒泡排序、雞尾酒攪拌排序、攪拌排序、漣漪排序、來回排序或快樂小時排序, 是冒泡排序的一種變形。該算法與冒泡排序的不同處在於排序時是以雙向在序列中進行排序。
//作者:bootloader
//2022年3月27日 21:09 周六
//獲取數組上限
#upBound := UPPER_BOUND(ARR := #arraySort, DIM := 1);
//獲取數組下限
#lowBound := LOWER_BOUND(ARR := #arraySort, DIM := 1);
//--記錄最后一次交換的位置--
#lastRightExchangeIndex := 0; //右邊界最后交換位置
#lastLeftExchangeIndex := 0; //左邊界最后交換位置
//--無序數列的邊界,每次比較只需要比到這里為止--
#rightUnsortBorder := #upBound - 1; //右邊界初始位置
#leftUnsortBorder := #lowBound; //左邊界默認位置
FOR #i := #lowBound TO #upBound / 2 DO //數組長度的一半
//有序標記,每一輪的初始值都是true
#isSorted := TRUE;
//奇數輪,從左向右比較和交換
FOR #j := #i TO #rightUnsortBorder DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] > #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
#isSorted := FALSE; //有元素交換,所以不是有序的,標記為false
#lastRightExchangeIndex := #j; //更新為最后一次交換元素的位置
END_IF;
ELSE
//降序
IF #arraySort[#j] < #arraySort[#j + 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j + 1];
#arraySort[#j + 1] := #tmpInt;
#isSorted := FALSE; //有元素交換,所以不是有序的,標記為false
#lastRightExchangeIndex := #j; //更新為最后一次交換元素的位置
END_IF;
END_IF;
END_FOR;
#rightUnsortBorder := #lastRightExchangeIndex;
IF #isSorted THEN
RETURN;
END_IF;
//偶數輪,從右到左的循環,將#isSorted重新標記為true
#isSorted := TRUE;
FOR #j := (#upBound - #i) TO (#leftUnsortBorder + 1) BY -1 DO
IF NOT #mode THEN
//升序
IF #arraySort[#j] < #arraySort[#j - 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j - 1];
#arraySort[#j - 1] := #tmpInt;
//有元素交換,所以不是有序的,標記為false
#isSorted := FALSE;
//更新為最后一次交換元素的位置
#lastLeftExchangeIndex := #j;
END_IF;
ELSE
//降序
IF #arraySort[#j] > #arraySort[#j - 1] THEN
#tmpInt := #arraySort[#j];
#arraySort[#j] := #arraySort[#j - 1];
#arraySort[#j - 1] := #tmpInt;
//有元素交換,所以不是有序的,標記為false
#isSorted := FALSE;
//更新為最后一次交換元素的位置
#lastLeftExchangeIndex := #j;
END_IF;
END_IF;
END_FOR;
#leftUnsortBorder := #lastLeftExchangeIndex;
IF #isSorted THEN
RETURN;
END_IF;
END_FOR;
END_FUNCTION
快速排序_遞歸
//還未開始
快速排序_非遞歸
//還未開始
