子集樹和排列樹
阿新 • • 發佈:2018-11-07
子集樹
當所給的問題是從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;
}