1. 程式人生 > >全排列演算法的思想和C語言的程式碼實現

全排列演算法的思想和C語言的程式碼實現

一、演算法思想

1、根本思想:遞迴

2、舉例設R={3,5,8,2}為需要排列的元素集合,{3,5,8,2}的全排列=3後面跟著{5,8,2}的全排列+5後面跟著{3,8,2}的全排列+8後面跟著{3,5,2}的全排列+2後面跟著{3,5,8}的全排列。對於{5,8,2}的全排列=5後面跟著{8,2}的全排列+8後面跟著{5,2}的全排列+2後面跟著{5,8}的全排列。以此類推,直到到排列只剩下一個元素。

二、程式碼實現

#include <stdio.h> 

int n = 0;                            //n用來計全排列的總數
int main()                         //主函式
 {   int list[] = {3,5,8,2};    
     perm(list, 0, 3);
     printf("total:%d\n", n);     //輸出n的個數
    
 } 


void perm(int list[], int begin, int end)      //產生list[begin:end]的所有排列
 {    
     int i;    
     if  (begin == end)        //begin等於end,即list中只有一個元素時
     {         
         for(i = 0; i <= begin; i++)            
             printf("%d ", list[i]);         //打印出這個排列
         printf("\n");        
         n++;                 //n的個數加一,表示又有一種情況產生了
     }    
     else    
     {        
         for(i = begin; i <= end; i++)       //還有多個元素待排列,依次產生:3後面跟著{5,8,2}的全排列+5後面跟著{3,8,2}的全排列+8後面跟著{3,5,2}的全排列+2後面跟著{3,5,8}的全排列 
         {            
             swap(&list[begin], &list[i]);             
             perm(list, begin + 1, end);            
             swap(&list[begin], &list[i]);        
         }    
     }
 }

void swap(int *a, int *b)           //用來交換兩個變數值的函式
 {    
     int m;    
     m = *a;    
     *a = *b;    
     *b = m;
 } 

三、程式碼解釋補充

1、  對於    
         for(i = begin; i <= end; i++)       
         {            
             swap(&list[begin], &list[i]);             
             perm(list, begin + 1, end);            
             swap(&list[begin], &list[i]);        
         }    

 每次都會先將整組數中的所有的數分別與第一個數交換,這樣就總是在處理後n-1個數的全排列。

2、在permut函式for迴圈中,呼叫完permut之後還要執行一次swap的,要把陣列還原成未呼叫permut之前的狀態,保證下一次迴圈或者上一級迴圈swap陣列元素的正確。