2021資料結構CH05 樹與二叉樹

2021-10-25 18:58:32 字數 4254 閱讀 3317

#include#include#define maxsize 5

#define elemtype int//假設元素型別為int

typedef struct bitreebitnode,*bitree;

typedef structstk;

void initstk(stk &s)

//入棧操作

bool push(stk &s,elemtype &x)

//出棧操作

bool pop(stk &s,elemtype &x)

//棧的判空

bool stackempty(stk s)

//讀取棧頂元素,返回棧頂元素的指標

gettop(s,p);

void lrn_stack(bitree t)

else

else

} }}

從上到下,從左到右,依次入隊,並且依次出隊,但不訪問,而是入棧,全部入棧之後再全部出棧即可。

void levelorde***n(bitree t)

if(p->rchild)

} while(isempty(s)!=false)

}

//遞迴法 

int btdepth1(bitree t)

int ldep=btdepth1(t->lchild);

int rdep=btdepth1(t->lchild);

if(ldep>rdep)

return ldep++;

else

return rdep++;

}//非遞迴法、

void btdepth2(bitree t)

if(p->rchild)

if(front==last)

} return level;

}

bool iscomplele(bitree t)

else//當前出隊結點為空

while(!isempty(q))

} return 1;

}

int i=0;

int preorder(bitree t)

}int visit(bitnode *p)

int inorder(bitree t)

}

int i=1;

elemtype preorder(bitree t,int k)

bitree del_x_tree(bitree b)

}void searchxfather(bitree b,int x)

else

else

enqueue(q,p->lchild);

}if(p->rchild)

else

enqueue(q,p->rchild);}}}

bool printxzuxian(bitree b,int x)

else //與上乙個if並列,沒有則返回false

return false;

}

後序遍歷非遞迴演算法的邏輯:在遍歷中,棧內元素都是當前元素的直系祖先

typedef structqu;

int biwidth(bitree b)

if(p->rchild)

} //通過上面的**,所有結點所處在的層數均記錄在level陣列中了

k=1;//回到第一層,即從level的第乙個元素開始遍歷,找到出現最多的數是誰,即找到樹寬

int max=0,i=0,n;

while(i<=qu.rear)

k=qu.level[i];//i不斷往前走,k的值也不斷更新

if(n>max)

max=n;

} return max;

}

對於滿二叉樹,把pre轉換成post

如上圖,實際上就是把pre中的根1放到post中的根2,把pre中的左子樹1放到post中的左子樹2,把pre中的右子樹1放到post中的右子樹2。在每次遞迴轉換的過程中把pre中的根1放到post中的根2,遞迴到最後的結果是只剩乙個根節點需要轉換。

所以最重要的就是找到pre中的起始和結尾位置分別對應於post中的起始和結尾位置。

遞迴轉換到倒數第二輪的時候,pre一定只剩下三個結點,即根左右,此時仍舊只把根的位置轉換好。

繼續遞迴則只剩下乙個結點,仍舊把他視為根節點,把pre中的根1放到post中的根2完成所有結點的轉換,如下圖。

本題**如下:

void pretopost(elemtype pre,int f1,int r1,elemtype post,int f2,int r2)

}

linklist head;

pre=null;

linklist inorder(bitree b)

else

} inorder(b->rchild);

b->rchild=null;

} return head;

}

三種情況 兩空,一空,零空

bool similar(bitree a,bitree b)

}

線索二叉樹的相關知識沒有考過

int wpl(bitree b)

int preorderwpl(bitree b,int deep)

return wpl;

}

void bitreetoe(bitree b)//次優解答,不考慮何時加括號,每時每刻加括號即可
孩子兄弟表示法:左孩子右兄弟,故用孩子兄弟表示法儲存森林時葉子結點無左孩子,右孩子可有可無。求葉子結點數,即求無左孩子的結點有多少個。

遍歷森林:

1.樹為空,葉子結點不存在,return 0;

2.當前遍歷結點有兩種情況

若左子樹為空,則葉子結點數為:1+右子樹的葉子節點數

若左子樹不為空,則葉子結點數為:左子樹的葉子節點數+右子樹的葉子節點數

typedef struct node*tree;

int yezi(tree b)

對於一棵單獨的樹(即非森林),化作孩子兄弟表示法儲存結構時,因為一棵樹不存在「兄弟」,所以這棵樹的根節點一定是沒有右孩子的。求這棵樹的高度,就要分清這棵樹的左子樹的情況。

在孩子兄弟表示法儲存結構中,樹根的左子樹可能有左子樹或者右子樹。樹根的左子樹的深度是樹根的左子樹的左子樹的深度+1與樹根的左子樹的右子樹的深度之中較大的乙個。

所以對於整棵樹而言,樹的深度其實就是樹根的左孩子深度+1,所以樹在遍歷樹根的左子樹的過程中會遞迴進入樹根的左子樹的左子樹或者樹根的左子樹的右子樹,每一部分的左子樹和右子樹的高度都會被不斷求出來,可能返回l+1,也可能返回r,而在遞迴完成後,樹的高度一定是返回l+1的,因為樹沒有「兄弟」,不可能返回r。

用遞迴求一棵樹的高度時,不是簡單的以為一棵樹只有左孩子,沒有右孩子,那麼最後樹高等於左子樹的高度+1就行了。而要明白遞迴總是把一棵樹看成更小的一棵樹,而這個更小的樹可能是有兄弟的,兄弟可能也有其它的兄弟,他們之中最高的高度才是最大樹的左孩子的高度,這段話可能對糾結樹高的返回值明明是l+1,為什麼還要返回l+1或者r中的某乙個有所幫助。

具體**如下:

typedef struct node*tree;

int level(tree t)

}

需要設定乙個輔助陣列存放層次序列,然後依次將這個陣列的元素鏈結起來。

#define maxsize 15

typedef struct csnode*cstree;

void creatcstree(cstree t,elemtype e,int degree,int n)

for(i=0;ilchild=p[k];//構建第i個結點的孩子結點

for(j=2;j<=d;j++)

} }t=p[0];

delete p;

}

05 資料結構與演算法 佇列

created by chen da 佇列類似生活中的排隊,為fifo結構。兩個基本操作 入隊push和出隊pop。用單鏈表可以實現,雙鏈表雖然可以,但是操作比較複雜。先實現乙個單鏈表 class node object def init self,value none,next none self...

資料結構 樹與二叉樹

一 性質 1 在二叉樹中,第i層的結點總數不超過2 i 1 2 深度為h的二叉樹最多有2 h 1個結點 h 1 最少有h個結點 3 對於任意一棵二叉樹,如果其葉結點數為n0,而度數為2的結點總數為n2,則n0 n2 1 4 具有n個結點的完全二叉樹的深度為int log2n 1 5 給定n個節點,能...

資料結構 樹與二叉樹

1 樹的定義 樹是一種 非線性的資料結構。樹是n n 0 個結點的有限集,在任意一棵非空樹中 1 有且僅有乙個特定的被稱為 根 root 的結點 2 當n 1時,其餘結點可分為m m 0 個互不相交的有限集,其中每個集合本身又是一棵樹,並且稱為根的 子樹 subtree 3 每棵子樹也是由唯一的根結...