数据结构 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但是这种可变编码是无法实现的


相关文章
|
11天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
54 16
|
11天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
56 8
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
18 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
17 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
1月前
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
26 1
|
1月前
|
算法 Java C语言
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
23 1
|
1月前
|
Java C++
【数据结构】探索红黑树的奥秘:自平衡原理图解及与二叉查找树的比较
本文深入解析红黑树的自平衡原理,介绍其五大原则,并通过图解和代码示例展示其内部机制。同时,对比红黑树与二叉查找树的性能差异,帮助读者更好地理解这两种数据结构的特点和应用场景。
25 0
|
1月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
1月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
23 0

热门文章

最新文章