『壹』 二叉樹的創建
如輸入ABCD#
是不能建立一個完整的二叉樹的,
代碼中以字元'#'判斷是否是空結點,有N個結點就會有N+1個空結點。
從代碼中可以看出是先序歷遍(根-左-右),進行輸入的。
如果想得到二叉樹:
A
/ \
B C
/ \
D E
就要輸入:ABD##E##C##
就是:
A
/ \
B C
/ \ / \
D E # #
/ \ / \
# # # #
『貳』 二叉樹創建問題!
程序邏輯上有錯誤。
else{}裡面的代碼,生成根節點後,再調用create_btree();創建左子樹,調用create_btree()時再創建左子樹的根節點,然後再調用。就這樣一直循環下去。
輸入「#」的時候返回NULL,怎樣判斷這個NULL?如果生成的左子樹有節點右子樹沒有節點,怎樣判斷並返回上層節點?
你用筆按照你的程序寫一下生成二叉樹的過程就知道了。
『叄』 怎麼理解遞歸創建二叉樹
遞歸=傳遞+回歸,即任務的下放和結果的回收。
這個需要自己慢慢體會,其實所有遞歸演算法實質上都是一樣的,理解了就萬變不離其宗了。
create(node *root)
{
root=new node;
寫上關於root的信息//初始化root節點
if(root滿足自定義的條件)//自定義一個遞歸的條件,即傳遞和回歸的界限,這是必須的。
{
create(root->lchild);//建左子樹
create(root->rchild);//建右子樹
}
}
總體上來看,建一顆樹,每一次調用creat()都是只創建一個節點,把剩下的任務下放給create(root->lchild)和create(root->rchild) ,而這兩個也會重復第一個create(root)的做法,實質體現的是任務的不斷下放,當達到最後的回歸的界限的,結果又將不斷回收,對應的是函數的不斷返回,實質是退棧的過程。這個過程其實經歷了一個不斷進棧和不斷出棧的過程,對應的是任務的不斷下放和不斷提交,最後棧空,即告全部任務完成!
pTree createTree(pTree T)
{
char ch;
ch = getchar();
if (ch == '#')//這是遞歸結束條件
{
T = NULL;
}
else
{
T = (pTree)malloc(sizeof(TreeNode));
T->data = ch;
T->left = createTree(T->left);//注意,這里採用的是先建左子樹
T->right = createTree(T->right);//再建右子樹,所以建樹時須按照相應的遍歷次序,即先序遍歷
}
return T;//這里不能缺,新建的樹,必須讓它的父親能指向它,如T->left = createTree(T->left);
}
}
『肆』 二叉樹怎麼建立
二叉樹建立方法:
『伍』 數據結構-二叉樹的創建
如果要在內存中建立一個如下左圖這樣的樹,wield能讓每個結點確認是否有左右孩子,我們對它進行擴展,變成如下右圖的樣子,也就是將二叉樹中的每個結點的空指針引出一個虛結點,其值為一個特定值,比如」#」,稱之為擴展二叉樹。擴展二叉樹就可以做到一個遍歷序列確定一棵二叉樹了。如前序遍歷序列為AB#D##C##。
//創建樹方法二
intCreateTree2(BiTree*t)
{
charch;
scanf("%c",&ch);
if(ch=='#')
{
(*t)=NULL;
}
else
{
(*t)=(BiTree)malloc(sizeof(BitNode));
if((*t)==NULL)
{
fprintf(stderr,"malloc()errorinCreateTree2.
");
returnERROR;
}
(*t)->data=ch;
CreateTree2(&((*t)->lchild));
CreateTree2(&((*t)->rchild));
}
returnOK;
}
其實建立二叉樹,也是利用了遞歸的原理。只不過在原來應該列印結點的地方,改成生成結點、給結點賦值的操作而已。因此,完全可以用中序或後序遍歷的方式實現二叉樹的建立,只不過代碼里生成結點和構造左右子樹的代碼順序交互一下即可。
『陸』 如何構建一顆二叉樹
//二叉樹結點類型為字元型的情況
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define null 0
#define MaxSize 1024
typedef struct tree
{ /*聲明樹的結構*/
struct tree *left; /*存放左子樹的指針*/
struct tree *right; /*存放右子樹的指針*/
char data; /*存放節點的內容*/
} treenode, * b_tree; /*聲明二叉樹的鏈表*/
b_tree Q[MaxSize];
/*建立二叉樹,按完全二叉樹的層次遍歷序列輸入*/
b_tree createbtree()
{
char ch;
int front,rear;
b_tree root,s;
root=NULL;
front=1;rear=0;
ch=getchar();
getchar();
while(ch!='?')
{
s=NULL;
if(ch!='.')
{
s=(b_tree)malloc(sizeof(treenode));
s->data=ch;
s->left=NULL;
s->right=NULL;
}
rear++;
Q[rear]=s;
if(rear==1)
root=s;
else
{
if(s&&Q[front])
if(rear%2==0)
Q[front]->left=s;
else
Q[front]->right=s;
if(rear%2==1)
front++;
}
ch=getchar();
getchar();
}
return root;
}
/*先序遍歷列印二叉排序樹*/
void preorder_btree(b_tree root)
{
b_tree p=root;
if(p!=null)
{
printf("%3c",p->data);
preorder_btree(p->left);
preorder_btree(p->right);
}
}
/* 中序遍歷列印二叉排序樹*/
void inorder_btree(b_tree root)
{
b_tree p=root;
if(p!=null){
inorder_btree(p->left );
printf("%3c",p->data );
inorder_btree(p->right );
}
}
/*後序遍歷列印二叉排序樹*/
void postorder_btree(b_tree root)
{
b_tree p=root;
if(p!=null)
{
postorder_btree(p->left );
postorder_btree(p->right );
printf("%3c",p->data );
}
}
/*求樹的高度*/
int treedepth(b_tree bt)
{
int hl,hr,max;
if(bt!=null)
{
hl=treedepth(bt->left);
hr=treedepth(bt->right);
max=(hl>hr)?hl:hr;
return (max+1);
}
else
return 0;
}
int count=0;
/*求葉子結點總數*/
int leafcount(b_tree bt)
{
if(bt!=null)
{
leafcount(bt->left);
leafcount(bt->right);
if(bt->left==null&&bt->right==null)
count++;
}
return count;
}
void paintleaf(b_tree bt)
{
if(bt!=null)
{
if(bt->left==null&&bt->right==null)
printf("%3c",bt->data);
paintleaf(bt->left);
paintleaf(bt->right);
}
}
typedef b_tree ElemType ;
int main()
{
char nodelist[MaxSize];
int len,flag;
char cmd;
b_tree root;
do
{
printf(" 輸入c......選擇創建一棵二叉排序樹\n");
printf(" 輸入a......將結束本程序\n\n");
flag=0;
do
{
if(flag!=0)
printf("選擇操作錯誤!請重新選擇!\n");
fflush(stdin);
scanf("%c",&cmd);
flag++;
}while(cmd!='c'&&cmd!='a');
if(cmd=='c')
{
printf("請輸入那你所要創建的二叉樹的結點的值,以'?'結束):\n");
getchar();
root=createbtree();
do
{
flag=0;
printf("\n\n 請選擇你要對這棵二叉樹所做的操作:\n\n");
printf(" x......先序遍歷\n");
printf(" z......中序遍歷\n");
printf(" h......後序遍歷\n");
printf(" b......層次遍歷\n");
printf(" d......求二叉樹的深度\n");
printf(" y......求葉子總數並輸出各葉子結點\n");
printf(" q......結束操作\n\n");
do
{
if(flag!=0)
printf("選擇操作錯誤!請重新選擇!\n");
fflush(stdin);
scanf("%c",&cmd);
flag++;
}while(cmd!='x'&&cmd!='z'&&cmd!='h'&&cmd!='b'&&cmd!='d'&&cmd!='y'&&cmd!='j'&&cmd!='q');
switch(cmd)
{
case 'x':
printf("\n先序遍歷開始:\n");
preorder_btree(root);
printf("\n先序遍歷結束\n\n");
break;
case 'z':
printf("\n中序遍歷開始:\n");
inorder_btree(root);
printf("\n中序遍歷結束\n\n");
break;
case 'h':
printf("\n後序遍歷開始:\n");
postorder_btree(root);
printf("\n後序遍歷結束\n\n");
break;
case 'd':
printf("\n這棵二叉樹的高度:\n%d\n\n",treedepth(root));
break;
case 'y':
printf("\n這棵二叉樹的葉子結點為:\n");
paintleaf(root);
printf("\n");
count=0;
count=leafcount(root);
printf("\n這棵二叉樹的葉子總數為:\n%d\n\n",count);
count=0;
break;
}
}while(cmd!='q'&&cmd!='Q');
}
}while(cmd!='a'&&cmd!='A');
printf("****謝謝使用!歡迎指正!****\n\n");
return 0;
}
『柒』 中序建立二叉樹
中序創建二叉樹是不科學的,因為在創建完左子樹後,若此時根節點的設置值非法,此時左子樹的創建將無意義,而且需要釋放左子樹空間,工作會比較復雜。
typedef struct Node {
int data;
struct Node *left;
struct Node *right;
}TreeNode;
TreeNode * CreateTree()
{
int data;
TreeNode *root;
root = (TreeNode *) malloc (sizeof(TreeNode));
root->left = CreateTree(); //創建左子樹
scanf("%d", &data);
if (data != '#')
{
root->data = data;
} else {
//若要保證不發生內存泄露此處需要通過
//後序遍歷左子樹釋放全部結點空間
free(root);
return NULL;
}
root->right = CreateTree(); //創建右子樹
return root;
}
『捌』 二叉樹的創建,求救
試一下這個
#include "iostream.h"
#include "stdlib.h"
#include "stdio.h"
typedef char ElemType;//定義二叉樹結點值的類型為字元型
const int MaxLength=10;//結點個數不超過10個
typedef struct BTNode{
ElemType data;
struct BTNode *lchild,*rchild;
}BTNode,* BiTree;
void CreateBiTree(BiTree &T){//按先序次序輸入,構造二叉鏈表表示的二叉樹T,空格表示空樹
// if(T) return;
char ch;
ch=getchar(); //不能用cin來輸入,在cin中不能識別空格。
if(ch==' ') T=NULL;
else{
if(!(T=(BTNode *)malloc(sizeof(BTNode)))) cout<<"malloc fail!";
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T){//先序遍歷
if(T){
cout<<T->data<<' ';
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T){//中序遍歷
if(T){
InOrderTraverse(T->lchild);
cout<<T->data<<' ';
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T){//後序遍歷
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<' ';
}
}
void LevelOrderTraverse(BiTree T){//層序遍歷
BiTree Q[MaxLength];
int front=0,rear=0;
BiTree p;
if(T){ //根結點入隊
Q[rear]=T;
rear=(rear+1)%MaxLength;
}
while(front!=rear){
p=Q[front]; //隊頭元素出隊
front=(front+1)%MaxLength;
cout<<p->data<<' ';
if(p->lchild){ //左孩子不為空,入隊
Q[rear]=p->lchild;
rear=(rear+1)%MaxLength;
}
if(p->rchild){ //右孩子不為空,入隊
Q[rear]=p->rchild;
rear=(rear+1)%MaxLength;
}
}
}
//非遞歸的先序遍歷演算法
void NRPreOrder(BiTree bt)
{ BiTree stack[MaxLength],p;
int top;
if (bt!=NULL){
top=0;p=bt;
while(p!=NULL||top>0)
{ while(p!=NULL)
{
cout<<p->data;
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{ top--; p=stack[top]; p=p->rchild; }
}
}
}
//非遞歸的中序遍歷演算法
void NRInOrder(BiTree bt)
{ BiTree stack[MaxLength],p;
int top;
if (bt!=NULL){
top=0;p=bt;
while(p!=NULL||top>0)
{ while(p!=NULL)
{
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{ top--; p=stack[top];cout<<p->data; p=p->rchild; }
}
}
}
//非遞歸的後序遍歷演算法
/*bt是要遍歷樹的根指針,後序遍歷要求在遍歷完左右子樹後,再訪問根。
需要判斷根結點的左右子樹是否均遍歷過。
可採用標記法,結點入棧時,配一個標志tag一同入棧
(1:遍歷左子樹前的現場保護,2:遍歷右子樹前的現場保護)。
首先將bt和tag(為1)入棧,遍歷左子樹;
返回後,修改棧頂tag為2,遍歷右子樹;最後訪問根結點。*/
typedef struct
{
BiTree ptr;
int tag;
}stacknode;
void NRPostOrder(BiTree bt)
{
stacknode s[MaxLength],x;
BiTree p=bt;
int top;
if(bt!=NULL){
top=0;p=bt;
do
{
while (p!=NULL) //遍歷左子樹
{
s[top].ptr = p;
s[top].tag = 1; //標記為左子樹
top++;
p=p->lchild;
}
while (top>0 && s[top-1].tag==2)
{
x = s[--top];
p = x.ptr;
cout<<p->data; //tag為R,表示右子樹訪問完畢,故訪問根結點
}
if (top>0)
{
s[top-1].tag =2; //遍歷右子樹
p=s[top-1].ptr->rchild;
}
}while (top>0);}
}//PostOrderUnrec
int BTDepth(BiTree T){//求二叉樹的深度
if(!T) return 0;
else{
int h1=BTDepth(T->lchild);
int h2=BTDepth(T->rchild);
if(h1>h2) return h1+1;
else return h2+1;
}
}
int Leaf(BiTree T){//求二叉樹的葉子數
if(!T) return 0;
else if(!T->lchild&&!T->rchild) return 1;
else return(Leaf(T->lchild)+Leaf(T->rchild));
}
int NodeCount(BiTree T){//求二叉樹的結點總數
if(!T) return 0;
else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
void main(){
BiTree T;
T=NULL;
int select;
//cout<<"請按先序次序輸入各結點的值,以空格表示空樹(輸入時可連續輸入):"<<endl;
// CreateBiTree(T);
while(1){
cout<<"\n\n請選擇要執行的操作:\n";
cout<<"1.創建二叉樹\n";
cout<<"2.二叉樹的遞歸遍歷演算法(前、中、後)\n";
cout<<"3.二叉樹的層次遍歷演算法\n";
cout<<"4.求二叉樹的深度\n";
cout<<"5.求二叉樹的葉子結點\n";
cout<<"6.求二叉樹的結點總數\n";
cout<<"7.二叉樹的非遞歸遍歷演算法(前、中、後)\n"; //此項可選做
cout<<"0.退出\n";
cin>>select;
switch(select){
case 0:return;
case 1:
cout<<"請按先序次序輸入各結點的值,以空格表示空樹(輸入時可連續輸入):"<<endl;
CreateBiTree(T);
break;
case 2:
if(!T) cout<<"未建立樹,請先建樹!";
else{
cout<<"\n先序遍歷:\n";
PreOrderTraverse(T);
cout<<"\n中序遍歷:\n";
InOrderTraverse(T);
cout<<"\n後序遍歷:\n";
PostOrderTraverse(T);
}
break;
case 3:
cout<<"\n層序遍歷:\n";
LevelOrderTraverse(T);
break;
case 4:
cout<<"二叉樹的深度為:\n";
cout<<BTDepth(T);
break;
case 5:
cout<<"\n葉子節點數:\n";
cout<<Leaf(T);
break;
case 6:
cout<<"總節點數:\n";
cout<<NodeCount(T);
break;
case 7:
if(!T) cout<<"未建立樹,請先建樹!";
else{
cout<<"\n先序遍歷:\n";
NRPreOrder(T);
cout<<"\n中序遍歷:\n";
NRInOrder(T);
cout<<"\n後序遍歷:\n";
NRPostOrder(T);
}
break;
default:
cout<<"請確認選擇項:\n";
}//end switch
}//end while
}
先輸入1
然後輸入回車
再輸入123
再輸入一個空格
再輸入4
再輸入三個空格
再輸入56
再輸入三個空格
再輸入輸入回車
一定要照這循序輸這輸不要亂敲回車和其他鍵
你試一下這個吧裡面還有說明
『玖』 創建二叉樹,完全看不懂
void CreatBiTree(BiTree &T)
{
//前序法創建二叉樹
//前序遍歷首先訪問根結點然後遍歷左子樹,最後遍歷右子樹
char ch;
if((ch=getchar())=='\n') // 遍歷結束判斷
//為啥getchar()沒有參數傳進去啊?怎麼取得當前節點的內容啊
T=NULL;
else
{
T=(BiTNode*)malloc(sizeof(BiTNode)); //分配空間作為根節點
if(!T) //沒有分配成功就退出
exit(1);
T->data=ch; //把當前節點作為根節點
CreatBiTree(T->lchild);//遞歸遍歷左子樹
CreatBiTree(T->rchild);///遞歸遍歷右子樹
}
}
要是這都看不懂,我也沒有辦法了。
『拾』 如何構建二叉樹
先序遞歸創建二叉樹,並對其進行 先序、中序、後序遍歷
1.建立二叉樹
2.為了直觀的輸出樹,那麼可以選擇廣度遍歷。查查書應該有。
3.深度的話我這剛好有兩個函數
#include <stdlib.h>
typedef struct{
char data;
}TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree;
void CreateBiTree(BiTree &T)
{
char ch;
TElemType elem;
printf("請輸入樹節點, 空樹以#代替:");
scanf("\n%c", &ch);
elem.data = ch;
if(ch == '#')
{
T = NULL;
}
else
{
T = (BiTNode * )malloc(sizeof(BiTNode));
if(!T) exit(-1);
T->data = elem; //生成根
CreateBiTree(T->lchild);//構造左子樹
CreateBiTree(T->rchild);// 構造右子樹
}
}
void main()
{
BiTree T;
CreateBiTree(T);
}