数据结构 C5树与二叉树

简介: 数据结构 C5树与二叉树

@[TOC]二叉树代码部分


二叉树的链式存储结构


typedef struct bitnode{
Elemtype data;
struct bitnode *lchild ,*rchild;
}bidnode ,*bitree


二叉树的遍历(递归调用)


先序遍历:

void preorder(bitree (T))
if(T!=NULL){
visit(T);
preorder(T->lchild);
preorder(T->rchild);
}
}


中序遍历:

void inorder(bitree T){
if(T!=NULL){
inorder (T->lchild);
visit(T);
inorder(T->rchild);
}
}


后序遍历:

void postorder(bitree){
if(T!=NULL){
postorder(T->lchild);
postorder(T->rchild);
visit(T);
}
}


递归算法和非递归算法的转化


中序遍历的非递归调用算法:

void inorder2(bitree T){
  initstack(s);//初始化了一个栈s
  bitree p=T;//把T的地址给了指针变量p
  while(p||!Isempty(S)){ //啥时候循环?p=1即p不空,!Isempty(s)是指栈不空;最后栈空而且p=NULL
  if(p){
  push(s,p);
  p=p->lchild
  }
  else{
  pop(s,p);//意思就是出栈栈顶元素(这里的p你就理解成栈顶元素的地址就行了)
  visit(p);
  p=p->rchild;
  }
  }
}


先序遍历的非递归算法:

void preorder2(bitree T){
  initstack(s);
  bitree p=T;
  while(p||!isempty(S)){
  if(p){
    visit(p);//先访问p结点
    push(s,p);//把该点压入栈中
    p=p->lchild;//把左孩子的结点的地址给变量p
    }
  else{
    pop(s,p);
    p=p->rchild;
    }
  }
}


后序遍历的非递归算法:

void levellorder(bitree T){
  initqueue(Q);//初始化队列
  Bitree p;//定义p指针,指向二叉树结点类型的结构
  Enqueue(Q,p);//根结点入队;
  while(!Isempty(Q)){
  Dequeue(Q,p);//出队
  visit(p);
  if(p->lchild!=NULL)
    enqueue(q,p->lchild);
  if(p->rchild!=NULL)
    enqueue(q,p->rchild);
  }
}


线索二叉树


线索二叉树的储存结构;

typedef struct threadnode{
  elemtype data;
  struct threadnode *lchild,*rchild;
  int ltag,rtag;
}threadnode,*threadtree;


中序线索二叉树的构造:

void createinthread(threadtree T){
  threadtree pre=NULL;
  if(T!=NULL){
  inthread(T,pre);//非空二叉树 线索化
  pre->rchild=NULL;//处理遍历的最后一个结点
  pre->rtag=1;
}
}
void inthread(threadtree &p,threadtree &pre){
  if(p!=NULL){
  InThread(p->lchild,pre);
  if(p->lchild==NULL){
    P->lchild=pre;
    p->ltag=1;
    }
  if(pre!=NULL&&pre->rchild==NULL)
    pre->rchild=p;
    pre->rtag=1;
  }
  pre=p;
  inthread(p->rchild,pre);
  }


中序线索二叉树的遍历

threadnode *firstnode(threadnode *p){
  while(p->ltag==0) 
  p=p->lchild;
  return p;
}
threadnode *nextnode(threadnode *p){
  if(p->rtag==0) return firstnode(p->rchild);
  else return p->rchild; 
}
void inorder (threadnode *p){
for(threadnode*p=firstnode(T);p=NULL;p=Nextnode(p))
visit(p);
}


树的存储结构


双亲表示法:

#define max_tree_size 100
typedef struct{
  elemtype data;
  int parent;
  }ptnode;
typedef struct{
  ptnode nodes[max_tree_size];
  int n;
  }ptree;


孩子表示法:

#define max_tree_size  100
typedef struct{
  int child;
  struct cnode *next;
  }cnode;
typedef struct{
  elemtype data;
  struct cnode *child;
  }pnode;
typedef struct{
  pnode nodes[max_tree_size];
  int n;
  }ctree;


孩子兄弟表示法;

typedef  struct csnode{
  elemtype data;
  struct csnode *firstchild,*nextsibling;
}csnode,cstree;


并查集


并查集采用的是双亲表示(顺序存储结构):


结构定义如下:
#define max_tree_size 100
typedef struct{
 elemtype data;
 int parent;
 }ptnode;
typedef struct{
 ptnode nodes[max_tree_size];
 int n;
 }ptree;
 由于data与数组编号一样的,那么就不需要上面这样定义结构体了
直接定义一个一维数组就可以了;
并查集结构定义如下:
#define SIZE 100
int ufsets[SIZE];
初始化:
Initial(S);
void Initial(int S[]){
    for(int i=0;i<size;I++)
    S[I]=-1;
}
查找操作:
Find(S,x);
int Find(int S[],int x){
    while(S[x]>=0)
  x=S[x];
    return x;
}   
合并操作:
Union(S,Root1,Root2);
void Union(int S[],int root1,int root2){
    S[Root2]=Root1;
}


树与二叉树的应用


二叉排序树


查找非递归调用算法:
BSTnode *BST_search(bitree T,Elemtype key{
    while(T!=NULL&&key!=T->data){
  if(key<T->data)
  T=T->lchild;
  else 
  T=T->rchild;
  }
  return T;
  }
插入:
int BST_Insert (Bitree &T,KeyType k){
    if(T==NULL){
  T=(BiTree)malloc(sizeof(BSTNode));
  T->key=k;
  T->lchild=T->rchild=NULL;
  return 1;
  }
    else if(k==T->key)
  return 0;
    else if(k<T->key)
  return  BST_Insert(T->lchild,k);
    else 
  return BST_insert(T->rchild,k);
}
构造:
void Creat_BST(Bitree &T,KeyType str[],int n){
   T=NULL;
   int i=0;
   while(i<n){
    BST_Insert(T,str[i]);
    i++;
    }
}

平衡二叉树:


判断:
void Judge AVL(Bitree bt,int &balance ,int &h){//bt是一个树的指针地址,balance,h分别是两个可以改变的数值.balance 1是平衡,0是不平衡 
//为什么用引用,因为把该类型的变量传入函数中,调用的函数会对参数进行修改,之后要利用这些修改的参数值,所以用引用;
  int bl=0,br=0,hl=0,hr=0;
  if(bt==NULL){
  h=0;
  balance=1;
  }
  else if(bt->lchild==NULL&&bt->rchild==NULL){
  h=1;
  balance=1;
  }
  else{
  Judge_AVL(bt->lchild,b1,h1);//函数调用
  Judge_AVL(bt->rchild,br,hr);
  if(hl>hr)
    h=hl+1;
  else
    h=hr+1;
  if(abs(h1-hr)<2&&b1==1&&br==1)
    balance=1;
  else
    balance=0;    
  }
}


二叉树的应用


哈夫曼编码


固定长度编码:000001010010011100101011010110
helloworld
000 h
001 e
010 l
011 o
100 w
101 r
110 d


可变长度编码:
helloworld:0001001101110000
00 h
01 e
0 l
1 o
10 w
11 r
000但是这种可变编码是无法实现的


相关文章
|
2天前
|
前端开发 JavaScript 算法
JavaScript 中实现常见数据结构:栈、队列与树
JavaScript 中实现常见数据结构:栈、队列与树
|
3天前
|
机器学习/深度学习
数据结构-----树的易错点
数据结构-----树的易错点
17 4
|
3天前
|
存储 算法
实验 2:树形数据结构的实现与应用
实验 2:树形数据结构的实现与应用
7 0
|
3天前
|
算法 编译器 C语言
数据结构——二叉树四种遍历的实现-3
数据结构——二叉树四种遍历的实现
数据结构——二叉树四种遍历的实现-3
|
3天前
|
存储
数据结构——二叉树四种遍历的实现-2
数据结构——二叉树四种遍历的实现
数据结构——二叉树四种遍历的实现-2
|
3天前
|
机器学习/深度学习
数据结构——二叉树四种遍历的实现-1
数据结构——二叉树四种遍历的实现
数据结构——二叉树四种遍历的实现-1
|
3天前
|
存储 算法 C++
数据结构/C++:AVL树
数据结构/C++:AVL树
10 2
|
3天前
|
JSON 数据可视化 Shell
数据结构可视化 Graphviz在Python中的使用 [树的可视化]
数据结构可视化 Graphviz在Python中的使用 [树的可视化]
11 0
|
3天前
|
存储 缓存 算法
数据结构与算法 树(B树,B+树,红黑树待完善)
数据结构与算法 树(B树,B+树,红黑树待完善)
15 0
|
3天前
【数据结构】二叉树的三种遍历(非递归讲解)
【数据结构】二叉树的三种遍历(非递归讲解)
10 1