演算法導論第十五章15.5-2構造最優二叉搜尋樹
阿新 • • 發佈:2019-01-25
#include "StdAfx.h" #include <iostream> #include <vector> using namespace std; void optimal_bst(vector<double>&p,vector<double>&q,vector<vector<double>>&e,vector<vector<double>>&w,vector<vector<int>>&root) { int n = p.size() - 1; for(int i=1;i<=n+1;i++) { e[i][i-1] = q[i-1]; w[i][i-1] = q[i-1]; } for(int l=1;l<=n;l++) { for(int start = 1;start<=n-l+1;start++) { int end = start + l -1; w[start][end] = w[start][end-1] + p[end] + q[end]; e[start][end] = 1000; for(int r = start;r<=end;r++) { double t = e[start][r-1] + e[r+1][end] + w[start][end]; if(t<e[start][end]) { e[start][end] = t; root[start][end] = r; } } } } } void print(vector<vector<int>>root,int a,int b,int p) { if(p == -1) printf("k%d為根\n",root[a][b]); int r = root[a][b]; //左子樹 if(r == a) { printf("d%d是k%d的左孩子\n",a-1,a); } else { printf("k%d是k%d的左孩子\n",root[a][r-1],r); print(root,a,r-1,0); } //右子樹 if(r == b) { printf("d%d是k%d的右孩子\n",b,b); } else { printf("k%d是k%d的右孩子\n",root[r+1][b],r); print(root,r+1,b,0); } } int main() { //只需要修改這個陣列便能執行不同的例子 //演算法導論第三版 p231 15.5-2 double p1[] = {0, 0.04,0.06,0.08,0.02,0.10,0.12,0.14}; double q1[] = {0.06,0.06,0.06,0.06,0.05,0.05,0.05,0.05}; //演算法導論第三版 p227頁例子 //double p1[] = {0, 0.15,0.10,0.05,0.10,0.20}; //double q1[] = {0.05,0.10,0.05,0.05,0.05,0.10}; vector<double>p; vector<double>q; for(int i=0;i<sizeof(p1)/sizeof(double);i++) { p.push_back(p1[i]); q.push_back(q1[i]); } int n = p.size()-1; vector<vector<double>>e(n+2); vector<vector<int>>root(n+2); vector<vector<double>>w(n+2); for(int i=0;i<n+2;i++) { e[i].resize(n+2); root[i].resize(n+2); w[i].resize(n+2); } optimal_bst(p,q,e,w,root); print(root,1,n,-1); return 0; }