分层次组织在管理上具有更高的效率
查找:根据某个给定关键字K,从集合R中找出关键字与K相同的记录
静态查找:集合中记录是固定的,没有插入和删除操作,只有查找
动态查找:集合中记录时动态变化的,除查找,还可以发生插入和删除
1、结构体定义
typedef struct LNode *List;
struct LNode{
ElementType Element[MAXSIZE];
int Length;
};
2、顺序查找(带哨兵)
int SequentialSearch(List Tbl,ElementType k)
{//在Element[1]~Element[n]中查找关键字为K的数据元素
int i;
Tbl->Element[0]=K; //建立哨兵
for(i=Tbl->Length;Tble->Element[i]!=K;i--);
return i; //查找成功返回所在单元下标;不成功返回0
}
无哨兵的查找
int SequentialSearch(List Tbl,ElementType K)
{//在ElementType[1]~ElementType[n]中查找关键字K的数据元素
int i;
for(i=Tbl->Length;i>0&&Tbl->Element[i]!=K;i--);
return i;
}
2、方法二:二分查找(Binary Search)
假设n个数组元素的关键字满足有序(比如说小到大)k1<k2<.....kn,并且时连续存放(数组),那么就可以进行二分查找。
缺少代码
3、树的定义
树(Tree):n(>=0)个节点构成的有限集合,当n=0,称为空树,对于任一课非空树(n>0),它具备以下性质:
树中有一个称为“根(Root)”的特殊节点,用r表示;其余结点可分为m(m>0)个互不相交的有限集T1,T2....TN,其中每个集合本身又是一棵树,称原来树的“子树(subTree)”
树的一些基本术语
1、结点的度(Degree):结点的子树个数
2、树的度:树所有结点中最大的度数
3、叶结点:度为0的结点
4、父节点:有子树的结点是其子树的根结点的父节点
5、子节点:若A结点时B结点的父节点,则称B结点时A结点的子节点;子结点也称孩子结点
6、兄弟结点:具有同一父结点的个节点彼此时兄弟结点。
7、路径和路径长度:从结点n1到nk的路径为一个结点序列n1,n2......nk,ni是ni+1的父节点。路径包含边的个数为路径的长度。
9、祖先结点:沿树根到某一结点路径上的所有结点都是这个结点的祖先结点。
10、子孙结点:某一结点的字数中所有结点时这个结点的子孙。
11、结点的层次:规定根结点在1层,其他任一结点的层数时其父节点的层数加1.
12、树的深度:树中所有结点中的最大层次时这棵树的深度。
2、二叉树的定义
二叉树T:一个有穷的结点集合,这个集合可以为空,若部位空,则他是由分界点和称为其左子树TL和右子树TR的两个不相交的二叉树组成。二叉树的子树有左右顺序之分。
特殊二叉树:斜二叉树、完美二叉树、完全二叉树、完全二叉树
2.1、二叉树几个重要性质
数据对象集:一个有穷的结点集合。若不为空,则由根节点和其左、右二叉子树组成。
操作树:BT∈BinTree,item∈ElementType,重要操作有:
1、Boolean IsEmpty(BinTree BT):判别BT是否为空;
2、void Traversal(BinTree BT):遍历,按某顺序访问每个结点
3、BinTree CreatBinTree():创建一个二叉树 。
常用的遍历方法有:
void PreOrderTraversal(BinTree BT):先序——根,左子树,右子树;
void InOrderTraversal(BinTree BT):中序——左子树,根,右子树;
void PostOrderTraversal(BinTree BT):后续——左子树,右子树,根
void LevelOrderTraversal(BinTree BT):层次遍历,从上到下,从左到右
2.2、二叉树的存储结构
2.2.1、顺序存储结构
完全二叉树:按从上到下,从左到右顺序存储n个结点的完全二叉树的结点父子关系:
非根结点(序号i>1)的父节点的序号事|i/2|;
结点(序号为i)的左孩子的序号事2i,(若2i<=n,则没有左孩子)
结点(序号为i)的右孩子结点的序号是2i+1,(若2i+1<=n,则没有由孩子);
2.2.2、链表存储
typedef strcut TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode
{
ElementType Data;
BinTree Left;
BinTree Right;
};
2.3、二叉树的遍历
(1)先序遍历,访问根节点、然后遍历其左子树、再遍历其右子树
void PreOrderTraversal(BinTree BT)
{
if(BT){
printf(%d,BT->Data);
PreOrderTraversal(Bt->Left);
PreOrderTraversal(BT->Ritht);
}
}
(2)中序遍历,先遍历左子树,访问根节点,遍历其右结点。
void InOrderTraversal(BinTree BT)
{
if(BT)
{
InOrderTraversal(BT->Left);
printf("%d",BT->Data);
InorderTraversal(BT->Right)
}
}
(3)后续遍历
后续遍历其左子树,后续右子树,最后是根结点
void PostOrderTraversal(BinTree BT)
{
if(BT)
{
PostOrderTraversal(BT->Left);
PostOrderTraversal(BT->Right);
Printf("%d",BT->Data);
}
}
先序、中序、后序遍历过程:遍历过程中经过结点的路线一样,只是访问个节点的时机不同。
2.3 二叉树的非递归遍历
中序遍历非递归遍历算法,算法实现的基本思路:使用堆栈
遇到一个结点,就把他压栈,并去遍历她的子树;当左子树遍历结束后,从栈顶弹出这个结点并访问它;然后按其右指针再去中序遍历该结点的右子树
void InOrderTraversal(BinTree BT)
{
BinTree T=BT;
Stack S = CreatStack(MaxSize);//创建并初始化堆栈
while(T||!IsEmpty(s){
while(T){ //一直向左并将沿途结点压入堆栈
Push(S,T);
T=T->Left;
}
if(!IsEmpty(s)){
T=pop(S); //结点弹出堆栈
printf("%d",T->Data); //访问打印结点
T=T->Right; //转向右子树
}
}
}
4、层序遍历
队列实现:遍历从根节点开始,首先将根结点入队,然后开始执行:结点出队、访问该结点、其左右儿子入队
层序基本过程:先根节点入队,然后:
从队列中取出一个元素,访问该元素所指结点,若该元素所指结点的左、右孩子结点非空则将其左、右孩子的指针顺序入队。
void LevelOrderTraverl (BinTree BT)
{
Queue Q; BinTree T;
if(!BT) return; //若是空树则直接返回
Q = CreatQueue(MaxSize); //创建并初始化队列Q
AddQ(Q,BT);
while(!IsEmptyQ(Q))
{
T=DeleteQ(Q);
printf("%d\n",T->Data); //访问去除队列的结点
if (T->Left) AddQ(Q ,T->Left);
if(T->Right) AddQ(Q ,T->Right);
}
}
5、程序框架搭建
int main()
{
Tree R1,R2;
R1=BuildTree(T1); //建二叉树1
R2=BuildTree(T2); //剪二叉树2
if(lsomorphic(R1,R2)) printf("yes\n"); //判断是否同构并输出
else printf("No\n");
return 0;
}
如何建立二叉树
Tree BuildTree(struct TreeNode t[])
{
scanf("%d\n",&N)
if(N)
{
for(i=0;i<N;i++)check[i]=0;
for(i=0;i<N;i++)
{
scanf("%c%c%c\n",&T[i].Element,&cl,&cr);
if(cl!='-')
{
T[i].Left=cl-'0';
check[T[i].Left]=1;
}
else
T[i].Left=Null;
}
for(i=0;i<N;i++)
if(!check[i]) break;
Root=i;
}
return Root;
}
判断两个二叉树同构
int Isomorphic(Tree R1,Tree R2)
{
if((R1==Null)&&(R2==Null))
return 0;
if((R1==Null)&&(R2==Null))||((R1!=Null)&&(R2==Null))
return 0;
if(T1[R1].Element!=T2[R2].Element)
return 0;
if((T1[R1].Left==Null)&&(T2[R2].Left==Null))
return Isomorphic(T1[R1].Right,T2[R2].Right);
}
int Isomorphic(Tree R1,Tree R2)
{
if(((T1[R1].Left!=Null)&&(T2[R2].Left!=Null))&&
((T1[T1[R1].Left].Element)==T2[T2[R2].Left].Element) )
return (Isomorphic(T1[R1].Left,T2[R2].Left)&&
Isomorphic(T1[R1].Right,T2[R2].Right))
else
return (Isomorphic(T1[R1].Left,T2[R2].Right)&&
Isomorphic(T1[R1].Right,T2[R2].Left))
}