西门子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

快速排序_递归

//还未开始

快速排序_非递归

//还未开始
posted @ 2022-03-27 21:16  生命在等待中延续  阅读(1888)  评论(1编辑  收藏  举报