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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

树的更多相关算法-3

發布時間:2025/3/17 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树的更多相关算法-3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

此代碼包含了構建哈夫曼樹的代碼,在后面幾段
?

  • ?
  • //計算一個二叉樹的節點個數,可以把所有的節點入隊列,然后觀察其rear的值,就知道其節點的個數,??這是一種廣度的遍歷方法?
  • //下面的是一中深度的遍歷的方法??當節點為NULL時候,返回0,??當節點無子節點時,返回1?,?否則得話返回左右節點的總數?
  • int?Nodes(BTNode?*b)?
  • {?
  • ????int?num1?=?0,?num2?=?0;?
  • ????if(b?==?NULL)??return?0;?
  • ????else?if(b->lchild?==?NULL?&&?b->rchild?==?NULL)?return?1;?
  • ????else??
  • ????{?
  • ????????num1?=?Nodes(b->lchild);???????//此處記錄的是其左子樹的所有子節點的數目?
  • ????????num2?=?Nodes(b->rchild);??????//?此處記錄的是右子樹所有節點的數目?
  • ????????return?(num1?+?num2?+?1);?????//此處?返回其左子樹的數目+右子樹的數目+?本身的數目(也就是那個1)?
  • ????}?
  • }?
  • ?
  • void?LeafNodes(BTNode?*b,?int?&leafnum)??????//此函數記錄葉子節點的數目,?與上面的函數類似,不過因為此函數不用計數?枝節點的數目,?所以沒有num1?num2?等變量?
  • {????????????????????????????????????????????//?當其找到一個葉子節點的時候,就把葉子節點的計數器?++,???因為leafnum是?&傳參,?所以不用擔心?回代的問題?
  • ????if(b?==?NULL)?return?;?
  • ????else?if(b->lchild?==?NULL?&&?b->rchild??==?NULL)??++leafnum;?
  • ????else?
  • ????{?
  • ????????LeafNodes(b->lchild,leafnum);?
  • ????????LeafNodes(b->rchild,leafnum);?
  • ????}????
  • }?
  • ?
  • int?Nodes2(BTNode?*b)??????????????//此函數同樣是求?樹的葉子節點的數目?
  • {?
  • ????int?num1?=?0,?num2?=?0;?
  • ????if(b?==?NULL)??return?0;?
  • ????else?if(b->lchild?==?NULL?&&?b->rchild?==?NULL)?{??return?1;}?
  • ????else??
  • ????{?
  • ????????num1?=?Nodes2(b->lchild);????
  • ????????num2?=?Nodes2(b->rchild);????
  • ????????return?(num1?+?num2?);??????//此處不同的是?沒有?+?1,?產生的遞增效果就是??枝節點?不會被遞增上,?也就是說只有葉子節點才可以?對其產生作用。。。??此處加1?產生的作用是非常大的(因為遞增的原因)?
  • ????}?
  • }?
  • ?
  • void??DNodes(BTNode?*b,?int?&dnum)???????//此函數計算?有兩個子節點的?節點的個數?
  • {?
  • ????if(b?!=?NULL)????????????//當節點不為空的時候進行操作?
  • ????{?
  • ????????if(b->lchild?!=?NULL?&&?b->rchild?!=?NULL)?????//此處表示?遇到了有雙子節點的?節點?
  • ????????????++dnum;??????????????????????
  • ????????DNodes(b->lchild,dnum);???????????????????????//遍歷左子樹?
  • ????????DNodes(b->rchild,dnum);??????????????????????//遍歷右子樹??
  • ????}?
  • }?
  • ?
  • int?DNodes2(BTNode?*b)??????????????????????//此函數是求樹中?有雙子節點的節點的個數?
  • {?
  • ????int?num1?=?0,?num2?=?0,?n?=?0;?
  • ????if(b?==?NULL)?return?0;?
  • ????else?if(b->lchild?==?NULL?||?b->rchild?==?NULL)?n?=?0;????????//上面兩個表明不符合條件?把?n置為?0??
  • ????else?{?n?=?1;?}??????
  • ????num1?=?DNodes2(b->lchild);?
  • ????num2?=?DNodes2(b->rchild);?
  • ????return?(num2?+?num1?+?n);???????????????????????????//由題意知,?n的值只能為?0?或?1?
  • }?
  • ?
  • void??DNodes3(BTNode?*b,?int?&dnum)?????????//此函數也是求?一個樹中有多少個?雙節點?
  • {?
  • ????int?num1?=?0,?num2?=?0;?
  • ????if(b?!=?NULL)??????????????????????????//當節點不為空的時候進行?
  • ????{?
  • ????????if(b->rchild?==?NULL?||?b->lchild?==?NULL)???//當節點只有一個子節點的時候,進行遞歸操作?
  • ????????{?
  • ????????????DNodes3(b->lchild,?dnum);?
  • ????????????DNodes3(b->rchild,?dnum);?
  • ????????}else?
  • ????????{??
  • ????????????++dnum;??????????????????????????????????//當節點有兩個子節點的時候,?把計數器++,??然后繼續執行遞歸操作?
  • ????????????DNodes3(b->lchild,?dnum);?
  • ????????????DNodes3(b->rchild,?dnum);?
  • ????????}?
  • ????}?
  • }?
  • ?
  • ?
  • ?
  • void??DelTree(BTNode?*b)??//此函數用來釋放?樹中節點的所占用的空間,??釋放只能采用后序遍歷,不能使用先序或者中序遍歷,因為中有將子樹的空間釋放掉后才能釋放根節點的空間?
  • {?
  • ????if(b?!=??NULL)?
  • ????{???DelTree(b->lchild);?
  • ????????DelTree(b->rchild);???????????
  • ????????free(b);?
  • ????}?
  • }?
  • ?
  • void?Swap(BTNode?*&b)?????????//交換左右子樹??用到的還是?后序?遞歸?
  • {?
  • ????BTNode?*temp;?
  • ????if(b?!=?NULL)???????????//當節點存在的時候?進行操作?
  • ????{?
  • ????????Swap(b->lchild);?
  • ????????Swap(b->rchild);?
  • ????????temp?=?b->lchild;???????????//交換左右子樹?
  • ????????b->lchild?=?b->rchild;?
  • ????????b->rchild?=?temp;?
  • ????}?
  • }?
  • ?
  • //對樹的遞歸操作??莫過于先?遍歷左子樹,?在遍歷右子樹,?這是一個方面。?另一個方面是?先序?中序?還是后序?
  • ?
  • void?Swap1(BTNode?*b,?BTNode?*&b1)?????????????//此函數是由一個樹,重新構建得到其另外一個左右子樹交換的樹。?
  • {?
  • ????if(b?==?NULL)?
  • ????{?
  • ????????b1?=?NULL;?
  • ????}?
  • ????else?
  • ????{?
  • ????????b1?=?(BTNode?*)malloc(sizeof(BTNode));?
  • ????????b1->data?=?b->data;?
  • ????????Swap1(b->lchild,?b1->rchild);?
  • ????????Swap1(b->rchild,?b1->lchild);?
  • ????}?
  • }?
  • ?
  • void?ancestor(BTNode?*b,char?r,?char?s)???//此函數是求得?值為?r?s?節點的最近的祖先節點?
  • {???????????????????????????????????????//不是一般性本例子采用后序遍歷樹,?并且假設?r?節點在?s?節點的左邊?
  • ????BTNode?*st[MAXSIZE],??*temp,?*temp2;?//本函數的思路是,后序遍歷樹?把遇到的節點進棧(這時候入棧中的元素都是r的祖先節點),當先(因為規定r節點在s節點的左邊)遇到值為r節點的時候,就把棧的所有節點的值放入path數組,用以記錄訪問過的值?
  • ????int?top?=?-1;???????????????????????//當遇到值為s的節點時候,就比較path數組與棧中的節點值,直到第一個不同即為其共同的祖先節點(當出棧的時候把?其不是公共的節點給出去了)?
  • ????bool??flag?=?true;?
  • ????char?path[MAXSIZE];?
  • ?????
  • ????if(b?!=?NULL)????????
  • ????{?
  • ????????temp?=?b;?
  • ????????do??????//此循環是后序遍歷?
  • ????????{????????
  • ????????????while(temp?!=?NULL)????????//把左子樹遞歸進棧?
  • ????????????{?
  • ????????????????++top;?
  • ????????????????st[top]?=?temp;?
  • ????????????????temp?=?temp->lchild;?
  • ????????????}?
  • ????????????flag?=?true;??
  • ????????????temp2?=?NULL;?
  • ????????????while(flag?&&?top?>?-1)??
  • ????????????{?
  • ????????????????temp?=?st[top];?
  • ????????????????if(temp->rchild?==?temp2)?????????//當節點的右節點訪問過?或者?其右節點為空的時候,就訪問它?
  • ????????????????{????????????????????
  • ????????????????????if(temp->data?==?r)?????????//判斷節點的值是否為r?如果是就給path數組賦值?
  • ????????????????????{?
  • ????????????????????????for(int?loop1=0;?loop1?<=?top;?++loop1)?
  • ????????????????????????????path[loop1]?=?st[loop1]->data;?
  • ????????????????????????--top;???????????????????????//執行出棧操作?
  • ????????????????????????temp2?=?temp;???????????????//表示已經訪問過,,即對其做標記?
  • ????????????????????}else?if(temp->data?==?s)?
  • ????????????????????{?
  • ????????????????????????int?loop2?=?0;?
  • ????????????????????????while(st[loop2]->data?==?path[loop2])?
  • ????????????????????????????++loop2;?
  • ????????????????????????cout<<r<<"?與?"<<s<<"?,?最近的共同祖先是?:"<<path[--loop2]<<endl;?
  • ????????????????????????return?;?
  • ????????????????????}else?
  • ????????????????????{?
  • ????????????????????????--top;?
  • ????????????????????????temp2?=?temp;?
  • ????????????????????}?
  • ????????????????}else?
  • ????????????????{?
  • ????????????????????flag?=?false;?????????????????//此語句塊表示當其右子節點沒有被訪問的時候,就跳出循環用flag做標志變量,?然后對其右子樹執行遞歸操作?
  • ????????????????????temp?=?temp->rchild;?
  • ????????????????}?
  • ????????????}?
  • ????????}while(top?>?-1);?
  • ????}?
  • }?
  • char?path1[MAXSIZE];?
  • int?top?=?-1;?
  • void?AncestorPath(BTNode?*b,?char?s)?????//此函數實現的是輸出根節點到?值為?s?節點之間的路徑,采用的遞歸操作?
  • {???????????????????????????????????????//這是一種先序遍歷?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????++top;?
  • ????????path1[top]?=?b->data;??????//入棧?
  • ????????if(b->data?==?s)???????????//判斷是否滿足條件?
  • ????????{??
  • ????????????cout<<"路徑為:"<<endl;?
  • ????????????for(int?loop1?=?0;?loop1?<=?top;?++loop1)?
  • ????????????????cout<<path1[loop1]<<'?';?
  • ????????????cout<<endl;?
  • ????????????return;?
  • ????????}?
  • ????????AncestorPath(b->lchild,s);?
  • ????????AncestorPath(b->rchild,s);?
  • ????????--top;?????????????????//恢復環境?
  • ????}?
  • }?
  • //此上下兩個函數?先序?與?后序的區別是?先序是先判斷是否滿足條件在進行?遍歷左子樹,??后序則是先深度遍歷左子樹,在判斷右子樹的時候,才判斷是否滿足條件?
  • //不管怎么說都?在棧中存在的元素都是所求的元素的??祖先節點?
  • void?AncestorPath2(BTNode?*b,?char?s)????//此函數同樣是實現?根節點到值為s的節點之間路徑輸出,采用的方法是后序法,與求兩個?節點?最近的祖先節點方法類似?
  • {?
  • ????BTNode?*st[MAXSIZE],?*temp,?*temp2;?
  • ????int?top?=?-1;?
  • ????bool?flag?=?true;?
  • ????char?path[MAXSIZE];?
  • ?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????temp?=?b;?
  • ????????do?
  • ????????{?
  • ????????????while(temp?!=?NULL)?
  • ????????????{?
  • ????????????????++top;?
  • ????????????????st[top]?=?temp;?
  • ????????????????temp?=?temp->lchild;?
  • ????????????}?
  • ????????????temp2?=?NULL;?
  • ????????????flag?=?true;?
  • ????????????while(flag?&&?top?>?-1)?
  • ????????????{?
  • ????????????????temp?=?st[top];?
  • ????????????????if(temp->rchild?==?temp2)?
  • ????????????????{?
  • ????????????????????if(temp->data?==?s)?
  • ????????????????????{?
  • ????????????????????????cout<<"根節點到?"<<s<<"?之間的路徑為?:"<<endl;?
  • ????????????????????????for(int?loop1?=?0;?loop1?<=?top;?++loop1)?
  • ????????????????????????????cout<<st[loop1]->data<<'?';?
  • ????????????????????????cout<<endl;?
  • ????????????????????????return;?
  • ????????????????????}?
  • ????????????????????--top;?
  • ????????????????????temp2?=?temp;?
  • ????????????????}else?
  • ????????????????{?
  • ????????????????????flag?=?false;?
  • ????????????????????temp?=?temp->rchild;?
  • ????????????????}?
  • ????????????}?
  • ?
  • ????????}while(top?>?-1);?
  • ????}?
  • }?
  • char?path3[MAXSIZE];?
  • int?top2?=?-1;?
  • void?Link(BTNode?*b)??????????//先序找樹中的葉子節點?
  • {?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????if(b->lchild?==?NULL?&&?b->rchild?==?NULL)?
  • ????????????path3[++top2]?=?b->data;?
  • ????????else?
  • ????????{?
  • ????????????Link(b->lchild);?
  • ????????????Link(b->rchild);?
  • ????????}?
  • ????}?
  • }?
  • ?
  • void?Link2(BTNode?*b)??????????//采用中序遍歷?找葉子節點?
  • {?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????Link2(b->lchild);?
  • ????????if(b->lchild?==?NULL?&&?b->rchild?==?NULL)?
  • ????????????path3[++top2]?=?b->data;?
  • ????????Link2(b->rchild);?
  • ????}?
  • }?
  • ?
  • void?Print(BTNode?*b,int?w)?????????????//把樹向?逆時針旋轉90度打印出來?
  • {?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????Print(b->rchild,?w+5);?
  • ????????for(int?loop1?=?0;?loop1?<=?w;?++loop1)?
  • ????????????cout<<'?';?
  • ????????cout<<b->data<<endl;?
  • ????????Print(b->lchild,w+5);?
  • ????}?
  • }?
  • ?
  • float?ExpValue(BTNode?*b)??????//此函數是計算一個樹組成的表達式?
  • {?
  • ????if(b?!=?NULL)??????????????//當其不為0的時候執行操作?
  • ????{????????
  • ????????switch(b->data)?
  • ????????{?
  • ????????case?'+'?:?
  • ????????????return?ExpValue(b->lchild)?+?ExpValue(b->rchild);??break;?
  • ????????case?'-'?:?
  • ????????????return?ExpValue(b->lchild)?-?ExpValue(b->rchild);??break;?
  • ????????case?'*'?:?
  • ????????????return?ExpValue(b->lchild)?*?ExpValue(b->rchild);??break;?
  • ????????case?'/'?:?
  • ????????????return?ExpValue(b->lchild)?/?ExpValue(b->rchild);??break;?
  • ????????default?:?
  • ????????????return?b->data?-?'0';???????????//此處目前只能是各位數,如果節點的值是數的話,就直接返回?
  • ????????}?
  • ????}?
  • }?
  • ?
  • bool?bflag?=?false;??????????//左子樹的標記?
  • bool?bflag2?=?false;????????//右子樹的標記?
  • void??InorderExp(BTNode?*b)???????//此函數是通過樹求得其表達式,?思路是當節點的數據域是符號的時候,就把其與左節點的數據域比較,如果左節點的數據域是符號并且?
  • {???????????????????????????????//子節點的優先級比根節點的小,那么就輸出‘(’并把標記設置為true,??????當遍歷右子樹的時候仍然拿其與右子樹的數據域比較如果,其符號的優先級比右子樹的優先級大,?
  • ????if(b?!=?NULL)???????????????//就輸出一個‘(’然后設置標記為true?
  • ????{?
  • ?????????
  • ????????switch(b->data)?
  • ????????{?
  • ????????case?'+'?:?
  • ????????case?'-'?:?
  • ????????????InorderExp(b->lchild);????????//表示先遍歷左子樹?
  • ????????????cout<<b->data<<'?';?????????//輸出其值?
  • ????????????InorderExp(b->rchild);?break;??//遍歷右子樹?
  • ????????case?'*'?:?
  • ????????case?'/'?:???????????????//當遇到?*?/的時候就應當判斷優先級了?
  • ????????????if(b->lchild?!=?NULL)???????//此處是判斷左子樹?
  • ????????????{?
  • ????????????????if(b->lchild->data?==?'+'?||?b->lchild->data?==?'-')?
  • ????????????????{???cout<<'(';?
  • ????????????????????bflag?=?true;?
  • ????????????????}?
  • ????????????}?
  • ?
  • ????????????InorderExp(b->lchild);?
  • ?????????????
  • ????????????if(bflag)?
  • ????????????{?cout<<')';??bflag?=?false;}?
  • ?????????
  • ????????????cout<<b->data<<'?';?????????//此處才是輸出?*?或者/?的地方,也就是在?‘(’‘)’都輸出完成的時候,如果有的話?
  • ?????????????
  • ????????????if(b->rchild?!=?NULL)???????//此處判斷右子樹?
  • ????????????{?
  • ????????????????if(b->rchild->data?==?'+'?||?b->rchild->data?==?'-')?
  • ????????????????{???cout<<'(';???????????????
  • ????????????????????bflag2?=?true;?
  • ????????????????}?
  • ????????????}?
  • ????????????InorderExp(b->rchild);?
  • ?????????????
  • ????????????if(bflag2)?
  • ????????????{?cout<<')';?bflag2?=?false;?}?
  • ????????????break;?
  • ????????default?:?
  • ????????????cout<<b->data<<'?';?
  • ????????????break;?
  • ????????}?
  • ????}????
  • }?
  • ?
  • int?process(char?op1,?char?op2)?//此函數是判斷優先級?
  • {?
  • ????if(op1?!=?'+'?&&?op1?!=?'-'?&&?op1?!=?'*'?&&?op1?!=?'/')??return?-1;??
  • ????if(op2?!=?'+'?&&?op2?!=?'-'?&&?op2?!=?'*'?&&?op2?!=?'/')??return?-1;?
  • ?
  • ????if(op1?==?'+'?||?op1?==?'-')?
  • ????{?
  • ????????return?0;?
  • ????}?
  • ????if(op1?==?'*'?||?op1?==?'/')?
  • ????{?
  • ????????if(op2?==?'+'?||?op2?==?'-')?
  • ????????????return?1;?
  • ????}?
  • }?
  • ?
  • void?InorderExp2(BTNode?*b)????//此函數也是求得表達式?
  • {?
  • ????int?flag1?=?2;?
  • ????int?flag2?=?2;?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????if(b->lchild?!=?NULL)?
  • ????????{?
  • ????????????flag?=?process(b->data,b->lchild->data);?
  • ????????????if(flag?==?1)?cout<<'(';?
  • ????????????InorderExp(b->lchild);?
  • ????????????if(flag?==?1)?cout<<')';?
  • ????????}?
  • ????????cout<<b->data;?
  • ????????if(b->rchild?!=?NULL)?
  • ????????{?
  • ????????????flag2?=?process(b->data,b->rchild->data);?
  • ????????????if(flag2?==?1)?cout<<'(';?
  • ????????????InorderExp(b->rchild);?
  • ????????????if(flag2?==?1)?cout<<')';?
  • ????????}?
  • ????}?
  • }?
  • ?
  • float?value[MAXSIZE];?
  • ?
  • int?top22?=?-1;?
  • char?postExp[MAXSIZE];?
  • void?PostExp(BTNode?*b)???//此函數的目的是把樹轉換為后綴表達式,怎么轉換為后綴表達式呢????采用后序遍歷即可?
  • {???????????????????????//因為符號位總是位于雙親結點,這樣就能先把?數字位給進棧,?然后進棧符號位?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????PostExp(b->lchild);?
  • ????????PostExp(b->rchild);?
  • ????????++top22;?
  • ????????postExp[top22]?=?b->data;?
  • ????}?
  • }?
  • ?
  • void?CompValue(char?postExp[])?//此函數是為了通過后綴表達式來求得其值?
  • {???top?=?-1;?
  • ????char?ch;?
  • ????int?loop1?=?0;?
  • ????ch?=?postExp[loop1];?
  • ????float?lValue?=?0.0f,?rValue?=?0.0f,?fValue?=?0.0f;?
  • ????while(ch?!=?'\0')?
  • ????{?
  • ????????switch(ch)?
  • ????????{?
  • ????????case?'+'?:?
  • ????????????rValue?=?value[top];?
  • ????????????--top;?
  • ????????????lValue?=?value[top];?
  • ????????????fValue?=?lValue?+?rValue;?
  • ????????????value[top]?=?fValue;?
  • ????????????ch?=?postExp[++loop1];?
  • ????????????break;?
  • ????????case?'-'?:?
  • ????????????rValue?=?value[top];?
  • ????????????--top;?
  • ????????????lValue?=?value[top];?
  • ????????????fValue?=?lValue?-?rValue;?
  • ????????????value[top]?=?fValue;?
  • ????????????ch?=?postExp[++loop1];?
  • ????????????break;?
  • ????????case?'*'?:?
  • ????????????rValue?=?value[top];?
  • ????????????--top;?
  • ????????????lValue?=?value[top];?
  • ????????????fValue?=?lValue?*?rValue;?
  • ????????????value[top]?=?fValue;?
  • ????????????ch?=?postExp[++loop1];?
  • ????????????break;?
  • ????????case?'/'?:?
  • ????????????rValue?=?value[top];?
  • ????????????--top;?
  • ????????????lValue?=?value[top];?
  • ????????????if(rValue?==?0)??{?cout<<"發生除零錯誤。"<<endl;?exit(1);?}??
  • ????????????fValue?=?lValue?/?rValue;?
  • ????????????value[top]?=?fValue;?
  • ????????????ch?=?postExp[++loop1];?
  • ????????????break;?
  • ????????default?:?
  • ????????????fValue?=?float(?ch?-?'0');?????//因為數字位?是個位數,所以此處沒有進行處理?
  • ????????????++top;?
  • ????????????value[top]?=?fValue;?
  • ????????????ch?=?postExp[++loop1];?
  • ????????????break;?
  • ????????}?
  • ????}?
  • ????if(top?==?0)?
  • ????{?cout<<"所求的值為:"<<value[top]<<endl;?}?
  • ????else?
  • ????{?cout<<"求值錯誤。"<<endl;?}?
  • }?
  • ?
  • void?NodeToRoot(BTNode?*b)????//此函數是在結點中增加一個雙親域以后,?輸出每個結點到根節點的路徑?
  • {???????????????????????????//采用先序遍歷?
  • ????BTNode?*temp;?
  • ????if(b?!=?NULL)?
  • ????{?
  • ????????temp?=?b;?
  • ????????while(temp?!=?NULL)?
  • ????????{?
  • ????????????cout<<temp->data<<'?';?
  • ????????????temp?=?temp->parent;?
  • ????????}?
  • ????????cout<<endl;?
  • ????????NodeToRoot(b->lchild);?
  • ????????NodeToRoot(b->rchild);?
  • ????}?
  • }?
  • ?
  • void?PreToPost(ElemType?pre[],?int?begin1,?int?end1,?ElemType?post[],?int?begin2,?int?end2)?
  • {???????????????????????????????//此函數將先序序列轉換為后序序列,?因為先序序列的第一個元素是后序序列的最后一個元素,??然后就以此為條件進行遞歸操作?
  • ????int?half?=?0;??
  • ????if(end1?>=?begin1)?
  • ????{???half?=?(end1?-?begin1?)?/?2;???????//half保存了中間的值?
  • ????????post[end2]?=?pre[begin1];??????
  • ????????PreToPost(pre,?begin1?+?1,?begin1?+?half,?post,?begin2,begin2?+?half?-1);?//此處是遍歷先序左子樹,?要注意的是在使用half的時候,應該加上開始點,??其half是一個區間,不是一個點,加上begin開始點后,才表示中間點的位置?
  • ????????PreToPost(pre,?begin1?+?half?+?1,?end1,?post,begin2?+?half,?end2?-1);?????//此處是遍歷先序右子樹?
  • ????}???
  • }?
  • ?
  • void?CreateHT(HTNode?ht[],?int?n)????//通過數組構造一棵哈夫曼樹,?因為一棵哈夫曼樹有n個節點的話,就會有總共2n?-?1?個節點?
  • {?
  • ????int?loop1?=?0,?loop2?=?0,?loop3?=?0,?lpos?=?0,?rpos?=?0;?
  • ????float?weight1?=?0.0f,?weight2?=?0.0f;??????//用來保存權值,其中weight1?保存的是較小的?
  • ?
  • ????for(loop1?=0;?loop1?<?n;?++loop1)????//此循環把雙親?左右孩子節點域置為?-1;?
  • ????{???ht[loop1].parent?=?-1;?
  • ????????ht[loop1].lchild?=?-1;?
  • ????????ht[loop1].rchild?=?-1;?
  • ????}?
  • ?
  • ????for(loop1?=?n;?loop1?<?2?*?n?+?1;?++loop1)?????//由于數組前面的n個節點是葉子節點,所以此處處理?后面的?n?-1?個非葉子節點?
  • ????{?
  • ????????weight1?=?32767.0f;?
  • ????????weight2?=?32767.0f;?
  • ?
  • ????????for(loop2?=?0;?loop2?<?loop1;?++loop2?)?
  • ????????{?
  • ????????????if(ht[loop2].parent?==?-1)?????????//只處理沒有雙親節點的?節點?
  • ????????????{?
  • ????????????????if(ht[loop2].weight?<?weight1)??????//保存最小的和?第二最小的權值及其位置?
  • ????????????????{?
  • ????????????????????weight2?=?weight1;?????rpos?=?lpos;?
  • ????????????????????weight1?=?ht[loop2].weight;??lpos?=?loop2;?
  • ????????????????}?
  • ????????????????else?if(ht[loop2].weight?<?weight2)?
  • ????????????????{?
  • ????????????????????weight2?=?ht[loop2].weight;?
  • ????????????????????rpos?=?loop2;?
  • ????????????????}?
  • ????????????}?
  • ????????}?
  • ????????ht[loop1].lchild?=?lpos;????ht[loop1].rchild?=?rpos;??ht[loop1].weight?=?ht[lpos].weight?+?ht[rpos].weight;?
  • ????????ht[lpos].parent?=?loop1;????ht[rpos].parent?=?loop1;?
  • ????}?
  • }?
  • //哈夫曼編碼只能是葉子節點,并且哈夫曼樹中只有度為?0?或2?的節點?
  • typedef?struct?
  • {?
  • ????char?cd[MAXSIZE];?//存儲根節點到葉子節點的編碼,即?0?或?1?
  • ????int?start;????????//開始位置?
  • }HCode;???//存儲哈夫曼遍歷的?節點結構?
  • /*?
  • void?CreateHCode(HTNode?ht[],?HCode?hcd[],?int?n)????//此函數是根據哈夫曼樹構造哈夫曼編碼,思路是從每個葉子節點開始遍歷到根節點,?如果節點是左節點?則表示為0?,如果右節點否則表示為1??
  • {?
  • ????int?loop1?=?0,?parent;?
  • ????HCode?hc;?
  • ????for(loop1?=?0;?loop1?<?n;?++loop1)?????//ht數組的前面n個元素是葉子節點,?所以遍歷前面n個節點?
  • ????{?
  • ????????hc.start?=?n;?
  • ????????parent?=?ht[loop1].parent;?
  • ?
  • ????????while(parent?!=?-1)?????????????//直到根節點?構造哈夫曼遍歷?
  • ????????{?
  • ????????????if(ht[parent].lchild?==?ht[loop1])??????//如果是左節點的話,為?0?
  • ????????????????hc.cd[hc.start--]?=?'0';?
  • ????????????else?
  • ????????????????hc.cd[hc.start--]?=?'1';???????????//否則為右節點,那么就為?1??
  • ????????????parent?=?ht[parent].parent;?????????//?
  • ?
  • ????????}?
  • ????????++hc.start;?
  • ????????hcd[loop1]?=?hc;?
  • ????}?
  • }?
  • */?
  • typedef?char?ElemType;?
  • typedef?struct?hnode?
  • {?
  • ????int?weight;?
  • ????ElemType?data;?
  • ????struct?hnode?*lchild,?*rchild;?
  • }HTree;?
  • ?
  • typedef?struct??
  • {?
  • ????ElemType?data;?
  • ????int?weight;?
  • }Node;?
  • typedef?struct??
  • {?
  • ????char?code[10];?
  • ????int?weight;?
  • ????ElemType?data;?
  • }NodeCode;?
  • ?
  • struct?cmp1?
  • {?
  • ????bool?operator()?(HTree?*node1,?HTree?*node2)?
  • ????{?
  • ????????return?node1->weight?>=?node2->weight;?
  • ????}?
  • };?
  • ?
  • void?CreateHuffm(HTree?*&root,?Node?nodes[],?int?num)?//此函數借助priority_queue<>?構造哈夫曼樹?
  • {?
  • ????int?loop1?=?0,?weight?=?0;?
  • ????HTree?*temp?=?NULL,*lchild?=?NULL,?*rchild?=?NULL;?
  • ????priority_queue<HTree?*,?vector<HTree?*>,?cmp1>??qp;?
  • ?
  • ????for(loop1?=?0;?loop1?<?num;?++loop1)?
  • ????{?
  • ????????temp?=?(HTree?*)malloc(sizeof(HTree));?
  • ????????temp->lchild?=?temp->rchild?=?NULL;?
  • ????????temp->data?=?nodes[loop1].data;?
  • ????????temp->weight?=?nodes[loop1].weight;?
  • ????????qp.push(temp);?
  • ????}?
  • ????while(qp.size()?!=?1)?
  • ????{?
  • ????????lchild?=?qp.top();?
  • ????????qp.pop();?
  • ????????rchild?=?qp.top();?
  • ????????qp.pop();?
  • ?????????
  • ????????temp?=?(HTree?*)malloc(sizeof(HTree));?
  • ????????temp->lchild?=?lchild;?
  • ????????temp->rchild?=?rchild;?
  • ????????temp->weight?=?lchild->weight?+?rchild->weight;?
  • ?????????
  • ????????qp.push(temp);???????
  • ????}?
  • ????root?=?qp.top();?
  • ????qp.pop();????
  • }?
  • ?
  • void?disp(HTree?*tree)?
  • {?
  • ????if(tree?!=?NULL)?
  • ????{?
  • ????????cout<<tree->weight<<endl;?
  • ????????disp(tree->lchild);?
  • ????????disp(tree->rchild);?
  • ????}?
  • }?
  • ?
  • ?
  • NodeCode?code[MAXSIZE];?
  • int?loop?=?0,?looop?=?0;?
  • char?pathx[10];?
  • ?
  • void?HuffmCode(HTree?*tree)??????//此函數求得每個節點的哈弗曼編碼,?利用先序遞歸的方式?
  • {?
  • ????if(tree?!=?NULL)?
  • ????{?
  • ????????if(tree->lchild?==?NULL?&&?tree->rchild?==?NULL)?
  • ????????{?
  • ????????????code[looop].data?=?tree->data;?
  • ????????????code[looop].weight?=?tree->weight;?
  • ????????????strcpy(code[looop].code,?pathx);????????????//此步驟沒用到loop的值,所以下面?
  • ????????????++looop;?
  • ????????}?
  • ????????if(tree->lchild?!=?NULL)?
  • ????????{?
  • ????????????pathx[loop]?=?'0';?
  • ????????????++loop;?
  • ????????????pathx[loop]?=?'\0';?????????????????//?????????????????????????????????????應該加上'\0'?
  • ????????????HuffmCode(tree->lchild);?
  • ????????}?
  • ????????if(tree->rchild?!=?NULL)?
  • ????????{?
  • ????????????pathx[loop]?=?'1';?
  • ????????????++loop;?
  • ????????????pathx[loop]?=?'\0';?
  • ????????????HuffmCode(tree->rchild);?
  • ????????}?
  • ????????--loop;?
  • ????????pathx[loop]?=?'\0';?
  • ????}?
  • }?
  • ?

    轉載于:https://blog.51cto.com/saibro/1183621

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的树的更多相关算法-3的全部內容,希望文章能夠幫你解決所遇到的問題。

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