zoukankan      html  css  js  c++  java
  • 最优二叉查找树optimalBSTC++实现

    算法参考《算法导论》第15章--动态规划

    //最优二叉查找树
    #include <cstdio>
    #include <cstring>
    #include <limits>
    class optimalBST{
    	private:
    		float *p, *q;
    		int n;
    		float **e;//(n+2)*(n+1)//e[1..n+1, 0..n] 
    		float **w;//(n+2)*(n+1)//w[1..n+1, 0..n]
    		int **root;//(n+1)*(n+1),0 row and 0 col are not used
    	public:
    		optimalBST(float pp[], float qq[], int nn){
    			n = nn;
    			p = new float[n + 1];
    			q = new float[n + 1];
    			memcpy(p, pp, (n + 1) * sizeof(pp));//sizeof(pp)==sizeof(float)
    			memcpy(q, qq, (n + 1) * sizeof(qq));
    			e = new float*[n + 2];
    			w = new float*[n + 2];
    			root = new int*[n + 1];
    			for(int i = 0; i <= n + 1; i++){//此处是n+1--之前写成n,导致段错误
    				e[i] = new float[n + 1];
    				w[i] = new float[n + 1];
    			}
    			for(int i = 0; i <= n; i++){
    				root[i] = new int[n + 1];
    			}
    		}
    		~optimalBST(){//不知道这么写析构函数对不对,不会有内存泄漏或者重复释放的问题吧?
    			delete []p;
    			delete []q;
    			for(int i = 0; i <= n + 1; i++){//此处是n+1--之前写成n,导致段错误
    				delete []e[i];
    				delete []w[i];
    			}
    			for(int i = 0; i <= n; i++){
    				delete []root[i];
    			}
    			delete []e;
    			delete []w;
    			delete []root;
    
    		}
    		void calBST(){//核心部分,算法见算法导论第15章
    			for(int i = 1; i <= n + 1; i++){
    				e[i][i - 1] = w[i][i - 1] = q[i - 1];
    			}
    			for(int l = 1; l <= n; l++){
    				for(int i = 1; i <= n - l + 1; i++){
    					int j = i + l - 1;
    					e[i][j] = std::numeric_limits<float>::max();
    					w[i][j] = w[i][j - 1] + p[j] + q[j];
    					for(int r = i; r <= j; r++){
    						float t = e[i][r - 1] + e[r + 1][j] + w[i][j];
    						if (t < e[i][j]){
    							e[i][j] = t;
    							root[i][j] = r;
    						}
    					}
    				}
    			}
    		}
    		void constructOptimalBST(){//练习15.5-1的算法
    			int r = root[1][n];
    			printf("k(%d) is root\n", r);
    			printBST(1, r - 1, 0);//0代表左子树
    			printBST(r + 1, n, 1);//1代表又子树
    		}
    		void printBST(int i, int j, int flag)//练习15.5-1的算法
    		{
    			if(j == i - 1){
    				if(flag == 0){
    					printf("d(%d)is k(%d)'s left child\n", i - 1, j + 1);
    				}else{
    					printf("d(%d)is k(%d)'s right child\n", i - 1, i - 1);
    				}
    			}else if(j >= i){
    				int r = root[i][j];
    				if(flag == 0){
    					printf("k(%d)is k(%d)'s left child\n", r, j + 1);
    				}else{
    					printf("k(%d)is k(%d)'s right child\n", r, i - 1);
    				}
    				printBST(i, r - 1, 0);
    				printBST(r + 1, j, 1);
    			}
    		}
    		void printBST2(int i, int j)//括号表示法:parent(left_subtree, right_subtree)
    		{
    			if(j == i - 1){
    				printf("d_%d", i - 1);
    			}else if(j >= i){
    				int r = root[i][j];
    				printf("k_%d(", r);
    				printBST2(i, r - 1);
    				printf(",");
    				printBST2(r + 1, j);
    				printf(")");
    			}
    		}
    		void printE()//e[1..n+1][0..n],打印e矩阵,格式同算法导论
    		{
    			for(int l = n; l >= 0; l--){
    				for(int i = 1; i <= n - l + 1; i++){
    					int j = i + l - 1;//[i..j] has l elements
    					printf("%f,", e[i][j]);
    				}
    				printf("\n");
    			}
    		}
    		void printRoot()//打印root矩阵,格式同算法导论
    		{
    			for(int l = n; l >= 1; l--){
    				for(int i = 1; i <= n - l + 1; i++){
    					int j = i + l - 1;//[i..j] has l elements
    					printf("%d,", root[i][j]);
    				}
    				printf("\n");
    			}
    		}
    
    };
    int main()
    {
    	int n = 7;
    	float p[7 + 1] = {0, 0.04, .06, .08, .02, .10, .12, .14};//练习15.5-2的数据
    	float q[7 + 1] = {.06, .06, .06, .06, .05, .05, .05, .05};
    	optimalBST bst(p, q, n);
    	bst.calBST();
    	bst.constructOptimalBST();
    	bst.printE();
    	bst.printRoot();
    	bst.printBST2(1, n);
    	printf("\n");
    	return 0;
    }
    

      

  • 相关阅读:
    CF869E The Untended Antiquity 解题报告
    Walk 解题报告
    CF911F Tree Destruction 解题报告
    P4397 [JLOI2014]聪明的燕姿
    洛谷 P2329 [SCOI2005]栅栏 解题报告
    洛谷 P3747 [六省联考2017]相逢是问候 解题报告
    set-erase
    set-empty
    set-empty
    set-end
  • 原文地址:https://www.cnblogs.com/fstang/p/2790777.html
Copyright © 2011-2022 走看看