查找:

  静态查找:集合中记录是固定的

      没有插入和删除操作,只有查找

  动态查找:集合中记录是动态变化的

      除查找,还可能发生插入和删除

  方法1:顺序查找

  

typedef struct LNode *List;
struct LNode{
    ElementType Element[MAXSIZE];
    int Length;
};

int SequentianlSerach(List Tb1,ElementType K)
{
    //在Element[1]~Element[n]中查找关键字为K的数据元素
    int i;
    Tb1->Element[0] = k;     //建立哨兵
    for(i = Tb1->Length;Tb1->Element[i]!=K;i--);
    return i;   //查找成功返回所在单元小标;不成功返回0
}

   方法二:二分查找。

from unittest.mock import right
int BinarySearch(List Tbl ,ElementType K)
{
    //在表Tbl中查找关键字为K的数据元素
    int left ,right,mid,NoFound=-1;
    
    left = 1;   //初始化左边界
    right = Tbl->Length;    //初始化右边界
    whlie(left <= right)
    {
        mid = (left+right)/2;   //计算中间元素坐标
        if( K < Tbl->Element[mid])
            right = mid-1;  //调整右边界
        else if(K > Tbl->Element[mid])
            left = mid+1;   //调整左边界
        else 
            return mid;     //查找成功,返回数据元素的下标
        }
        return NotFound;    //查找不成功,返回-1
}

  二分查找判定树:

    1. 判定树上每个结点需要的查找次数刚好为该结点所在层数;
    2. 查找成功时查找次数不会超过判定树的深度
    3. n个结点的判定树的深度为[log2 n]+1

树的定义、

    树(tree):n(n>20)个结点构成的有限集合。

      当n=0时 称为空树;

      对于任一非空树(n>0),它具备以下性质:

  1. 树中有一个称为“根(Root)”的特殊结点,用r表示;
  2. 其余结点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每个集合本身又是一棵树,称为原来树的“子树(SubTree)”

树与非树?

  1. 子树是不相交的;
  2. 除了根结点外,每个结点有且仅有一个父结点;
  3. 一棵树N个结点的树有N-1条边。 
  4. 有一个m棵树的集合(也叫森林)共有k条边,则这m棵树共有k+m个结点

树的一些基本术语:   

  1. 结点的度(Degree):结点的子树个数
  2. 树的度:树的所有结点中最大的度数
  3. 叶结点(Leaf):度为0的结点
  4. 父结点(Parent):有子树的结点是其子树的根结点的父结点
  5. 子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点;子结点也称孩子结点/
  6. 兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点。
  7. 路径和路径长度:从结点n1到nk 的路径为一个结点序列n1,n2,...nk ,ni是ni+1 的父结点。路径所包含边的个数为路径的长度
  8. 祖先结点(Ancestor):沿树根到某一结点路径上的所有结点都是这个结点的祖先结点
  9. 子孙节点(Descendant):某一结点的子树中的所有结点是这个结点的子孙。
  10. 结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1.((
  11. 树的深度(Depth):树中所有结点中的最大层次是这颗树的深度。

树的表示:

 儿子—兄弟表示法:

二叉树的定义

  二叉树T:一个有穷的结点集合。

     这个集合可以为空。

     若不为空,则它是由根结点和称为其左子树T和右子树TR的两个不相交的二叉树组成。

 

 

 

两个儿子的结点数+叶结点数=一个儿子的结点数+1;

 

 

二叉树的抽象数据类型定义

    类型名称:二叉树

     数据对象集:一个有穷的结点集合。

        若不为空,则由根结点和其左、右二叉子树组成。

     操作集:BT € BinTree,Item € ElementType,重要操作有:

    1. Boolean IsEmpty(BinTree BT):判别BT是否为空;
    2. void Traversal(BinTree BT):遍历,按某顺序访问每个结点;
    3. BinTree CreatBinTree():创建一个二叉树。

      常用的遍历方法有:

      1. void PreOrderTraversal(Bintree BT):先序---根、左子树、右子树;
      2. void lnOrderTraversal(Bintree BT):中序---左子树、根、右子树;
      3. void PostOrderTraversal(Bintree BT):后序---左子树、右子树、根;
      4. void LevelOrderTraversal(Bintree BT):层次遍历,从上到下、从左到右 

二叉树的存储结构

 

二叉树的遍历

     (1)先序遍历

        遍历过程为:

      1. 访问根结点;
      2. 先序遍历其左子树;
      3. 先序遍历其右子树。

顺序:A B D F E 

void PreOrderTraversal(BinTree BT)
{
    if(BT){
        printf("%d",BT->Data);
        PreOrderTraversal( BT->Left );
        PreOrderTraversal( BT->Right );
    }
}

 (2)中序遍历

  遍历过程为:

    1. 中序遍历其左子树;
    2. 访问根结点;
    3. 中序遍历其右子树。

顺序:D B E F A G H C I

 void InOrderTraversal( BinTree BT )
 {
     if( BT ) {
         InOrderTraversal( BT->Left );
         printf("%d", BT->Data);
         InOrderTraversal( BT->Right );
     }
 }

 

 (3)后序遍历

  遍历过程为:

    1. 后序遍历其左子树;
    2. 后序遍历其右子树;
    3. 访问根结点。

 

后序遍历:D E F B H G I C A

void PostOrderTraversal(BinTree BT)
{
    if( BT ){
        PostOrderTraversal( BT->Left );
        PostOrderTraversal( BT->Right );
        printf("%d",BT-Data);
    }
}

 

中序遍历非递归遍历算法

  1. 遇到一个结点,就把它压栈,并去遍历它的左子树;
  2. 当左子树遍历结束后,从栈顶弹出这个结点并访问它;
  3. 然后按其右指针再去中序遍历该结点的右子树。
void InOrderTraversal( BinTree BT )
{
    BinTree T = BT;
    stack S = CreatStack( MaxSize );    /*创建并初始化堆栈S*/
    while( T || !IsEmpty(S) ){
        while(T){   /*一直向左并将沿途结点压入堆栈*/
            Push(S,T);
            T = T->Left;
        }
        if(!IsEmpty(S)){
            T = Pop(S); /*结点弹出堆栈*/
            printf("%5d",T->Data);  /*(访问)打印结点*/
            T = T->Right;   /*转向右子树*/
        }
    }
}

先序遍历的非递归遍历算法:

void InOrderTraversal( BinTree BT )
{
    BinTree T = BT;
    stack S = CreatStack( MaxSize );    /*创建并初始化堆栈S*/
    while( T || !IsEmpty(S) ){
        while(T){   /*一直向左并将沿途结点压入堆栈*/
            Push(S,T);
            printf("%5d",T->Data);  /*(访问)打印结点*/
            T = T->Left;
        }
        if(!IsEmpty(S)){
            T = Pop(S); /*结点弹出堆栈*/
            T = T->Right;   /*转向右子树*/
        }
    }
}

 

posted @ 2019-03-18 22:01  殇之弑梦  阅读(131)  评论(0编辑  收藏  举报