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

快速排序_遞歸

//還未開始

快速排序_非遞歸

//還未開始


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM