日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

回溯法——打印子集树

發布時間:2024/4/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 回溯法——打印子集树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

打印子集樹。比如說有三個元素,用0和1表示子集有或者沒有這個元素,向左分支走為1,向右分支走為0,那么如下圖所有路徑都可以用0和1表示出來,可以用0和1完整表示子集。0就不打印對應的元素,1就打印對應的元素。比如三個元素是{1,2,3}路徑為{0,1,0}的話就打印{2};路徑為{1,1,0}的話就打印{1,2}。

遞歸代碼

void fun(int* ar, int* br, int i, int n) {if (i == n)//如果一條路徑走完了就打印{for (int j = 0; j < n; j++){if (br[j] == 1){cout << ar[j]<<" ";}}cout << endl;}else//左為1,右為0{br[i] = 1;fun(ar, br, i + 1, n);//leftbr[i] = 0;fun(ar, br, i + 1, n);//right} }int main() {const int n = 3;int ar[n] = { 1,2,3 };int br[n] = { 0,0,0 };fun(ar, br, 0, n);return 0; }

運行結果:

下面我們用非遞歸方法,用回溯法代碼打印子集樹。
先上代碼:

void Print(int* ar, int* br, int n) {for (int i = 0; i < n; ++i){if (br[i] == 1){printf("%2d", ar[i]);}}printf("\n"); }int main() {const int n = 3;int ar[n] = { 1,2,3 };int br[n] = { 0,0,0 };//初始化為-1,0 1,2是越界int i = 0;while (i >= 0){if (br[i] >= 2)//遇到2就回溯{--i;//回溯if (i != -1 && br[i] != 2){br[i] += 1;}}else//沒遇到2,向后走,如果整個數組都沒2就打印 {if (i == n - 1)//i走到了最后{Print(ar, br, n);br[i] += 1;}else//i沒有走到最后{++i;br[i] = 0;}}}return 0; }

運行結果:

分析:
br數組用1,0表示ar集合的子集和中元素的有無。
比如ar = {1,2,3}
br = {0,0,0}表示ar一個子集不含任何元素
br = {1,0,1}表示ar一個子集含有第一個元素1,和第三個元素3

br數組中在代碼循環中可能出現2,2是為了回溯用的,遇到2就回溯。
第一次的時候數組沒有2,i直接走到最后,br = {0,0,0}所以ar子集為空集,什么也沒打印。

第二次的時候打印完空集后,br[2]賦值為1,進入到下一次循環 ,沒有遇到2,不需要回溯,br = {0,0,1},打印。

第三次的時候,第二次打印完后,br[2] += 1,變成2,繼續進入下一次循環,i = 2,br[i] = 2,回溯i–,br[1]被賦值為1,此時br = {0,1,2},進入到下一次循環,將br[2]置為0。br = {1,0,1}打印。

第四次的時候,第三次打印完后,br[2] += 1, 變成1,進入下一次循環,沒遇到2,br = {0,1,1}打印。

第五次的時候,第四次打印完后,br[2] += 1, 變成2,進入下一次循環,回溯i–,br[1]+=1,變成2,繼續回溯,br[0]+=1,變成1,此時br = {1,2,2},i = 0,進入下兩次循環,將2都置為0。br = {1,0,0},打印。

第六次循環的時候,第五次打印完,br[2] += 1,變成1,進入下一次循環,沒有遇到2,沒有回溯,br = {1,0,1},打印。

第七次的時候,第六次打印完,br[2] += 1, 變成2,進入下一次循環,i = 2,br[2] = 2,回溯i–,變為1,br[1] += 1,變為1,進入下一次循環,將br[2]置為0,br = {1,1,0},打印。

第八次的時候,第七次打印完,br[2] += 1,變成1,進入下一次循環,沒有2,br = {1,1,1},打印。

第九次的時候,第八次打印完,br[2] +=1,變成1,進入下一次循環,br[2] = 2,回溯i–,變為1,br[1]+=1,變為2,進入下一次循環,br[1] = 2,回溯i–,變為0,br[0] += 1,變為2,再進入下一次回溯,i–,小于0, 退出循環,結束。

總結

以上是生活随笔為你收集整理的回溯法——打印子集树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。