西门子Protal_TIA SCL编程实例_排序算法
西门子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
快速排序_递归
//还未开始
快速排序_非递归
//还未开始