演算法導論第12章習題解

來源:互聯網
上載者:User

12-1-2:

二叉搜尋樹:left.key<key<eight.key;

最小堆:key<left.key,key<right.key;

不能,使用堆排序的話,得O(nlgn)

12-1-3:

這個已經在第十章做過了,

使用棧的話,有點浪費,因為使用棧,parent就用不上了;

不使用棧的情況,就是使用parent回溯父結點,對於x,我們已經有了尋找x後繼得程式:TERR-SUCCSSOR,我們從最小節點開始調用TREE-SUCCESSOR即可

12-1-4:

這個也已經做過了,此處不重複

12-2-1:

c

12-2-2:

TREE-MINIMUM(x) if(x.left!=NULL)   TREE-MINIMUM(x.left) else   return xTREE-MAXIMUM(x) if(x.right!=NULL)   TREE-MAXIMUM(x.right) else   return x

12-2-3:

見二叉搜尋樹的c++代碼

12-2-4:

12-2-5:

如果x有兩個孩子,那麼它的後繼y必然是右子樹中的最小值,所以y必然沒有左孩子,否則其左孩子必然小於y大於x;

同理,x有兩個孩子,那麼其前驅必然沒有右孩子

12-3-1:

TREE-INSERT(T,z,x)//將z插入到以x為根的子樹中 if(T.root=NIL)  T.root=z  return if(x.key<z.key)   if(x.right==NIL)     x.right==z     z.parent=x   else     TREE-INSERT(T,z,x.right) else   if(x.left==NIL)     x.left==z     z.parent=x   else     TREE-INSERT(T,z,x.left) 

12-3-3:

最壞情況下就是原來就是已序的,那麼構造的二叉搜尋樹就是一條鏈表,相當於進行插入排序,O(n^2)

最好的情況下,構造的是平衡的二叉樹,此時O(nlgn)

12-3-4:

不可交換

12-3-5:

//對於某一個節點,其右子樹上的節點都可以通過後繼得到TREE-SEARCH(T,k,begin,limit)//begin是起始點,limit是節點必須在limit的子樹中 current=begin next=current.p if(next==limit)//此時只有一個節點current,如果k不等於current.key,就沒有此節點   if(current.key==k)     return current   else return NIL while(next!=limit&&next.key<k)   current=next   next=next.p if(next.key==k)   return next; //此時要麼current.key<k<next.key,要麼current==樹根,但是x必然在current的右子樹中  TREE-SEARCH(T,k,current.succ,next)     //採用search的架構,但是,這裡必須增加一個參數begin_pro,它的後繼是begin //如果x稱為左孩子,那麼begin_pro的後繼是xTREE-INSERT(T,x,begin_pro,begin,limit) current=begin next=current.p if(next==limit)//此時只有一個節點current   if(x.key<current.key)//x成為current的左孩子     x.p=current begin_pro.succ=x x.succ=current   else//稱為右孩子     x.p=current x.succ=current.succ current.succ=x     while(next!=limit&&next.key<k)   current=next   next=next.p if(next.key==k)   return next; //此時要麼current.key<k<next.key,要麼current==樹根,但是x必然在current的右子樹中  TREE-INSERT(T,k,current,current.succ,next)//採用search的架構://對於某一個節點,其右子樹上的節點都可以通過後繼得到TREE-DELETE(T,k,begin_pro,begin,limit)//begin是起始點,limit是節點必須在limit的子樹中 current=begin next=current.p if(next==limit)//如果k存在,必然等於current.key   x=current.succ   begin_pro.succ=x   x.p=current.p while(next!=limit&&next.key<k)   current=next   next=next.p if(next.key==k)   return next; //此時要麼current.key<k<next.key,要麼current==樹根,但是x必然在current的右子樹中  TREE-DELETE(T,k,current,current.succ,next) 

12-3-6:

刪除前驅而非後繼得情況與刪除後繼得情況基本相同,

公平策略:可以傳遞bool值,每次刪除後,都對bool值取反,當bool為真時刪除後繼,為假時刪除前驅;

或者使用rand()隨機播放

12-1:

這個題給出了三種策略解決關鍵字相同的問題,每種策略都值得學習

12-2:

構造好樹之後先序輸出:

//本著簡潔的原則,我們這裡只實現insert和preorder#include<iostream>#include<string>using namespace std;struct node{string str;node* p;node* left;node* right;node(string a="",node* b=NULL,node* c=NULL,node* d=NULL):str(a),p(b),left(c),right(d){}};class radix_tree{public:node* root;radix_tree(){root=new node;}//root表示0位串void insert(string s);void preorder(){_preorder(root);}private:void _preorder(node* x);};void radix_tree::insert(string s){node* y=NULL;node* x=root;for(int i=0;i<s.length();++i){if(s[i]==0){if(x->left==NULL){//此時x沒有左孩子,建立一個y=new node;x->left=y;y->p=x;}x=x->left;}else{if(x->right==NULL){y=new node;x->right=y;y->p=x;}x=x->right;}}//此時x即為s的插入點x->str=s;}void radix_tree::_preorder(node* x){if(x==NULL)return;if(x->str!="")cout<<x->str<<'\n';_preorder(x->left);_preorder(x->right);}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.