㈠ C/C++ 搜索二叉樹相關
#include "iostream"
#include "string"
using namespace std;
string pro;
string origin;
struct Tree
{
char name;
Tree* l;
Tree* r;
Tree()
{
l=r=NULL;
}
};
bool equal(Tree *a,Tree *b)
{
if(a==NULL&&b==NULL)
return true;
else if(a==NULL&&b!=NULL||a!=NULL&&b==NULL)
return false;
if (a->name==b->name)
return equal(a->l,b->l)&&equal(a->r,b->r);
return false;
}
void insert(Tree** root,char c)
{
if (*root==NULL)
{
*root=new Tree;
(*root)->name=c;
}
else
{
if (c<(*root)->name)
insert(&(*root)->l,c);
else
insert(&(*root)->r,c);
}
}
int main()
{
int n,in;
while (scanf("%d",&n)!=EOF&&n!=0)
{
cin>>origin;
Tree *t1=NULL;
for(in=0;in<origin.length();in++)
insert(&t1,origin[in]);
for (int i=0;i<n;i++)
{
cin>>pro;
Tree *t2=NULL;
for(in=0;in<pro.length();in++)
insert(&t2,pro[in]);
if(equal(t1,t2))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
}
——來自網路。。
㈡ C語言二叉樹遍歷查找問題
二叉樹的遍歷分為以下三種:
先序遍歷:遍歷順序規則為【根左右】
中序遍歷:遍歷順序規則為【左根右】
後序遍歷:遍歷順序規則為【左右根】
什麼是【根左右】?就是先遍歷根,再遍歷左孩子,最後遍歷右孩子;
舉個例子,看下圖:
先序遍歷:ABCDEFGHK
中序遍歷:BDCAEHGKF
後序遍歷:DCBHKGFEA
以中序遍歷為例:
中序遍歷的規則是【左根右】,我們從root節點A看起;
此時A是根節點,遍歷A的左子樹;
A的左子樹存在,找到B,此時B看做根節點,遍歷B的左子樹;
B的左子樹不存在,返回B,根據【左根右】的遍歷規則,記錄B,遍歷B的右子樹;
B的右子樹存在,找到C,此時C看做根節點,遍歷C的左子樹;
C的左子樹存在,找到D,由於D是葉子節點,無左子樹,記錄D,無右子樹,返回C,根據【左根右】的遍歷規則,記錄C,遍歷C的右子樹;
C的右子樹不存在,返回B,B的右子樹遍歷完,返回A;
至此,A的左子樹遍歷完畢,根據【左根右】的遍歷規則,記錄A,遍歷A的右子樹;
A的右子樹存在,找到E,此時E看做根節點,遍歷E的左子樹;
E的左子樹不存在,返回E,根據【左根右】的遍歷規則,記錄E,遍歷E的右子樹;
E的右子樹存在,找到F,此時F看做根節點,遍歷F的左子樹;
F的左子樹存在,找到G,此時G看做根節點,遍歷G的左子樹;
G的左子樹存在,找到H,由於H是葉子節點,無左子樹,記錄H,無右子樹,返回G,根據【左根右】的遍歷規則,記錄G,遍歷G的右子樹;
G的右子樹存在,找到K,由於K是葉子節點,無左子樹,記錄K,無右子樹,返回G,根據【左根右】的遍歷規則,記錄F,遍歷F的右子樹;
F的右子樹不存在,返回F,E的右子樹遍歷完畢,返回A;
至此,A的右子樹也遍歷完畢;
最終我們得到上圖的中序遍歷為BDCAEHGKF,無非是按照遍歷規則來的;
根據「中序遍歷」的分析,相信先序遍歷和後序遍歷也可以輕松寫出~
㈢ C語言寫二叉樹查找,幫忙給看看~不知道錯誤在哪裡
你的創建函數很有問題,人家一般兩種格式:
T = Creat();
或者:
Create(T); //T應該為指針,不應該為非指針
你怎麼把這兩種混用了?即是要麼在Create()里分配內存然後返回該樹的地址,要麼就是把T作為參數傳進入,再分配,但這種只能是把指針傳進去,不把指針傳進去不行,值傳遞該知道不會改變實參的內容吧?
還有,沒有分配到內存的判斷時,是應該退出的,你怎麼還繼續操作了呢?沒分配到內存再操作肯定會出現異常的
PS:本來想幫你改一下的,但復制粘貼到VS沒換行,用word改有點麻煩,你自己再改改吧
㈣ 二叉樹結點的查找C語言實現
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct bitnode
{
char data;
struct bitnode *lchild, *rchild;
}bitnode, *bitree;
void createbitree(t,n)
bitnode ** t;
int *n;
{
char x;
bitnode *q;
*n=*n+1;
printf("\n Input %d DATA:",*n);
x=getchar();
if(x!=』\n』) getchar();
if (x==』\n』)
return;
q=(bitnode*)malloc(sizeof(bitnode));
q->data=x;
q->lchild=NULL;
q->rchild=NULL;
*t=q;
printf(" This Address is: %o, Data is: %c,\n Left Pointer is: %o, Right Pointer is: %o",q,q->data,q->lchild,q->rchild);
createbitree(&q->lchild,n);
createbitree(&q->rchild,n);
return;
}
void visit(e)
bitnode *e;
{
printf(" Address: %o, Data: %c, Left Pointer: %o, Right Pointer: %o\n",e,e->data,e->lchild,e->rchild);
}
void preordertraverse(t)
bitnode *t;
{
if(t)
{
visit(t);
preordertraverse(t->lchild);
preordertraverse(t->rchild);
return ;
}else return ;
}
void countleaf(t,c)
bitnode *t;
int *c;
{
if(t!=NULL)
{
if (t->lchild==NULL && t->rchild==NULL)
{*c=*c+1;
}
countleaf(t->lchild,c);
countleaf(t->rchild,c);
}
return;
}
int treehigh(t)
bitnode *t;
{int lh,rh,h;
if(t==NULL)
h=0;
else{
lh=treehigh(t->lchild);
rh=treehigh(t->rchild);
h=(lh>rh ? lh:rh)+1;
}
return h;
}
main()
{
bitnode *t; int count=0;
int n=0;
printf("\n Please input TREE Data:\n");
createbitree(&t,&n);
printf("\n This is TREE Struct: \n");
preordertraverse(t);
countleaf(t,&count);
printf("\n This TREE has %d leaves ",count);
printf(" , High of The TREE is: %d\n",treehigh(t));
}
㈤ 數據結構與演算法分析 —— C 語言描述:二叉樹
二叉樹(binary tree)是一棵樹,其中每個節點的兒子都不能多於兩個。
二叉樹的一個性質是平均二叉樹的深度要比 N 小的多,這個性質有時很重要。分析表明,這個平均深度為 ,而對於特殊類型的二叉樹,即二叉查找樹(binary search tree)。其深度的平均值是 。不幸的是,在最壞情況下,這個深度可以大到 N-1 的。
因為一棵二叉樹最多有兩個兒子,所以我們可以用指針直接指向它們。樹節點的聲明在結構上類似於雙鏈表的聲明,在聲明中,一個節點就是由 key(關鍵字)信息加上兩個指向其他節點的指針(Left 和 Right)組成的結構。
應用於鏈表上的許多法則也可以應用到樹上。特別地,當進行一次插入時,必須調用 malloc 創建一個節點。節點可以在調用 free 刪除後釋放。
我們可以用在畫鏈表時常用的矩形框畫出二叉樹,但是,樹一般畫成圓圈並用一些直線連接起來,因為二叉樹實際上就是圖(graph)。當涉及樹時,我們也不顯示地畫出 NULL 指針,因為具有 N 個節點的每一棵二叉樹都將需要 N+1 個 NULL 指針。
二叉樹有許多與搜索無關的重要應用。二叉樹的主要用處之一是在編譯器的設計領域。
上圖就是一個表達式樹(expression tree)。表達式樹的樹葉是操作樹(operand),比如常數或者變數,而其他的節點為操作符(operator)。由於這里所有的操作都是二元的,因此這棵特定的樹正好是二叉樹,雖然這是最簡單的情況,但是節點含有的兒子還是有可能多於兩個的。一個節點也有可能只有一個兒子,如果有一目減算符(unary minus operator)的情形。可以將通過遞歸計算左子樹和右子樹所得到的值應用在根處的算符操作中而算出表達式樹 T 的值。上面里的例子中,左子樹的值是「((3+1) 3)/((9-5)+2)」,右子樹的值是「(3 (7-4)+6)」,因此整棵樹的表達式就是圖上的結果。
我們可以通過遞歸產生一個帶括弧的左表達式,然後列印出在根處的運算符,最後再遞歸地產生一個帶括弧的右表達式而得到一個(對兩個括弧整體進行計算的)中綴表達式(infix expression)。這種一般的方法(左,節點,右)稱為中序遍歷(inorder traversal);由於其產生的表達式類型,這種遍歷很容易記憶。
另一個遍歷策略是遞歸列印出左子樹、右子樹,然後列印運算符。如果我們應用這種策略於上面的樹,則輸出將是「31+3 95-2+/743- 6+-」。這種遍歷策略一般稱為後序遍歷(postorder traversal)。
第三種遍歷策略是先列印出運演算法,然後遞歸地列印出右子樹和左子樹。同樣的,應用這種策略於上面的樹,則輸出將是「-/ ++313-952+ 3-746」,這是一種不太常用前綴(prefix)記法,這種遍歷策略為先序遍歷(preorder traversal)。
這里我們只給出一種演算法,來把後綴表達式轉變成表達式樹。這里的要點是,一次一個符號地讀入表達式。如果符號是操作符,那麼我們就建立一個單節點樹並將一個指向它的指針推入棧中。如果符號是操作符,那麼我們就從棧中彈出指向兩棵樹 和 的那兩個指針( 的先彈出)並形成一棵新的樹,該樹的根就是操作符,它的左、右兒子分別指向 和 。然後將這棵新樹的指針壓入棧中。