子集树和排列树


子集树

当所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间称为子集树。
比如,01背包问题就是子集树。这类问题通常有2^n个叶子节点,总节点个数是2^(n+1)-1。遍历子集树的任何算法都需要 O(2^n)的时间。

选取数字:

#include <stdio.h> #include <stdlib.h> #include <string.h>


void sel(int *arr, int len, int *ass, int index) { if (index == len) { for (int i = 0; i < len; ++i) { if (ass[i]) { printf("%d ", arr[i]); } } printf("\n"); } else { ass[index] = 1; sel(arr, len, ass, index+1); ass[index] = 0; sel(arr, len, ass, index+1); } } int main() { int arr[] = {1,3,5}; int len = sizeof(arr)/sizeof(int); int *ass = (int*)malloc(len * sizeof(int)); if (ass) { sel(arr, len, ass, 0); free(ass); } return 0; }

 

排列树

当所给问题是确定n个元素满足某种性质的排列时,相应的解空间树称为排列树。

排列树通常有n!个叶子节点。因此遍历排列树需要O(n!)的计算时间

 

数组全排列:

#include <stdio.h> #include <stdlib.h> #include <string.h>


void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } void permutation(int *arr, int len, int index) { if (index == len) { for (int i = 0; i < len; ++i) { printf("%d ", arr[i]); } printf("\n"); } else { for (int i = index; i < len; ++i) { swap(&arr[index], &arr[i]); permutation(arr, len, index+1); swap(&arr[index], &arr[i]); } } } int main() { int arr[] = {1,2,3}; int len = sizeof(arr)/sizeof(int); permutation(arr, len, 0); return 0; }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM