树(2)

Jun 07, 2016 pm 03:42 PM
主要 簡單 演算法 遞迴 遍歷

一:二叉树的遍历. 由于递归算法很简单,在这里就不例举了,主要看一下非递归算法(其实也就是用栈实现,因为递归本身就是一种栈) 1.先序遍历: 思想:(1)从根节点依次遍历当前节点的左子树,边遍历访问,并且压入栈 (2).再访问当前栈顶结点的右子树,然后再返回

一:二叉树的遍历.

     由于递归算法很简单,在这里就不例举了,主要看一下非递归算法(其实也就是用栈实现,因为递归本身就是一种栈)

     1.先序遍历:

          思想:(1)从根节点依次遍历当前节点的左子树,边遍历访问,并且压入栈

                   (2).再访问当前栈顶结点的右子树,然后再返回到(1)执行,直至栈空        

#define maxsize 100
typedef struct
{
    Bitree Elem[maxsize];
    int base,top;
}SqStack;

void PreOrderUnrec(Bitree t)
{
    SqStack s;
    StackInit(s);
    p=t;
    
    while (p!=null || !StackEmpty(s))
    {
        while (p!=null)             //遍历左子树
        {
            visite(p->data);
            push(s,p);
            p=p->lchild;       
        }//endwhile
        
        if (!StackEmpty(s))         //通过下一次循环中的内嵌while实现右子树遍历
        {
            p=pop(s);
            p=p->rchild;        
        }//endif                
    }//endwhile 
    
}//PreOrderUnrec
登入後複製
   2.中序遍历:

      思想:(1)从根节点遍历左子树,边遍历边入栈

               (2)弹出栈顶元素,并访问,然后访问当前栈顶的右子树,回到(1)

#define maxsize 100
typedef struct
{
    Bitree Elem[maxsize];
    int base,top;
}SqStack;

void InOrderUnrec(Bitree t)
{
    SqStack s;
    StackInit(s);
    p=t;
    while (p!=null || !StackEmpty(s))
    {
        while (p!=null)             //遍历左子树
        {
            push(s,p);
            p=p->lchild;
        }//endwhile
        
        if (!StackEmpty(s))
        {
            p=pop(s);
            visite(p->data);        //访问根结点
            p=p->rchild;            //通过下一次循环实现右子树遍历
        }//endif   
    
    }//endwhile
}//InOrderUnrec
登入後複製
 

3.后序遍历(其实还不是特清楚,代码来自百度):(需要设置一个标志量表示当前节点的右子树是否被访问)

#define maxsize 100
typedef enum{L,R} tagtype;//标记的类型,为R时表示当前结点的
typedef struct 
{
    Bitree ptr;
    tagtype tag;
}stacknode;

typedef struct
{
    stacknode Elem[maxsize];
    int base,top;
}SqStack;

void PostOrderUnrec(Bitree t)
{ 
    SqStack s;
    stacknode x;
    StackInit(s);
    p=t;
    
    do 
    {
        while (p!=null)        //遍历左子树
        {
            x.ptr = p; 
            x.tag = L;         //标记为左子树
            push(s,x);
            p=p->lchild;
        }
    
        while (!StackEmpty(s) && s.Elem[s.top].tag==R)//如果
        {
            x = pop(s);
            p = x.ptr;
            visite(p->data);   //tag为R,表示右子树访问完毕,故访问根结点       
        }
        
        if (!StackEmpty(s))
        {
            s.Elem[s.top].tag =R;     //遍历右子树
            p=s.Elem[s.top].ptr->rchild;        
        }    
  }while (!StackEmpty(s));
}//PostOrderUnrec
登入後複製


二.线索二叉树:

             含有n个结点的二叉树,一共有2n个指针域,有n+1个处于Null状态,为了使空间不浪费,可以让这些空的指针域指向二叉树各种遍历的前驱或后继结点,这样又可以方便查找每一个元素,而不必采用遍历,节省了时间

1.存储结构:

typedef enum { Link, Thread } PointerThr; 
    // Link==0:指针,Thread==1:线索
typedef struct BiThrNode{
    TElemType data;
    Struct BiThrNode *lchild, *rchild;    // 左右孩子指针
    PointerThr LTag, RTag;   // 左右标志,当LTag=Thread时,表示线索,为Link时表示指向下一结点
} BiThrNode, *BiThrTree;
登入後複製
树(2)

1)若结点有左子树,则lchild指向其左孩子;
       否则, lchild指向其直接前驱(即线索);

2).若结点有右子树,则rchild指向其右孩子;

     否则,rchild指向其后继(即线索);

例:

树(2)


2.线索二叉树的中序遍历算法:

Status IOTraver_T( BiThrTree T,Status (*Visit)(TElemType e) )
{ //T指向头结点,头结点的左链lchild指向根结点,中序遍历 //二叉线索树T的非递归算法,对每个数据元素调用函数Visit。
 p = T->lchild;  //p指向根结点     
 while (p != T) {     //空树或遍历结束时,p = = T
    while (p->LTag==Link) p = p->lchild;  
    if (!Visit(p->data)) return ERROR;  //访问其左子树为空的结点
    while (p->RTag==Thread && p->rchild!=T) 
       { p = p->rchild; Visit(p->data);  } //访问后继结点
    p = p->rchild; 
    }
 return OK;  
} // IOTraver_T
登入後複製

3.线索二叉树的生成算法:

void InThreading (BiThrTree p)//中序并线索化
 {
    if (p)
    {  
       InThreading( p->lchild );  // 左子树线索化
        if ( !p->lchild ) 
         { p->LTag=Thread; p->lchild=pre; }  // 前驱线索

        if ( !pre->rchild )
         { pre->RTag=Thread; pre->rchild=p; }  //后继线索
        pre = p;                         // 保持pre指向p的前驱
      InThreading(p->rchild);      //右子树线索化
     }
  } // InThreading
登入後複製
Status InorderThreading(BiThrTree  & Thrt, BiThrTree  T)
{ //中序遍历二叉树T,并将其中序线索化, Thrt 指向头结点.
   if ( ! (Thrt = (BiThrTree) malloc ( sizeof (BiThrnode) ) )  exit  ( OVERFLOW ) ;
   Thrt ->LTag = Link;   Thrt ->RTag = Thead;   // 建头结点
   Thrt ->rchild = Thrt ;                                       //右指针回指
   if ( !T ) Thrt ->lchild = Thrt ;    // 若二叉树空,则左指针回指
   else {
             Thrt ->lchild = T;     pre = Thrt; //将头结点与树相连
             <strong>InThreading(T);  </strong>        // 中序遍历进行中序线索化,调用上面的函数
             pre ->rchild = Thrt;   
             pre ->RTag = Thread;     //最后一个结点线索化
             Thrt ->rchild = pre;
            }
    return OK;
 } // InOrderThreading
登入後複製







本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1317
25
PHP教程
1268
29
C# 教程
1246
24
C++ 函式的遞歸實作:遞迴深度有限制嗎? C++ 函式的遞歸實作:遞迴深度有限制嗎? Apr 23, 2024 am 09:30 AM

C++函數的遞歸深度受到限制,超過此限制會導致堆疊溢位錯誤。限制值因係統和編譯器而異,通常在1000到10000之間。解決方法包括:1.尾遞歸最佳化;2.尾呼叫;3.迭代實作。

C++ lambda 表達式是否支援遞迴? C++ lambda 表達式是否支援遞迴? Apr 17, 2024 pm 09:06 PM

是的,C++Lambda表達式可以透過使用std::function支援遞歸:使用std::function捕捉Lambda表達式的參考。透過捕獲的引用,Lambda表達式可以遞歸呼叫自身。

使用C++實現機器學習演算法:常見挑戰及解決方案 使用C++實現機器學習演算法:常見挑戰及解決方案 Jun 03, 2024 pm 01:25 PM

C++中機器學習演算法面臨的常見挑戰包括記憶體管理、多執行緒、效能最佳化和可維護性。解決方案包括使用智慧指標、現代線程庫、SIMD指令和第三方庫,並遵循程式碼風格指南和使用自動化工具。實作案例展示如何利用Eigen函式庫實現線性迴歸演算法,有效地管理記憶體和使用高效能矩陣操作。

C++ 函式的遞迴實作:遞迴與非遞迴演算法的比較分析? C++ 函式的遞迴實作:遞迴與非遞迴演算法的比較分析? Apr 22, 2024 pm 03:18 PM

遞歸演算法透過函數自呼叫解決結構化的問題,優點是簡潔易懂,缺點是效率較低且可能發生堆疊溢位;非遞歸演算法透過明確管理堆疊資料結構避免遞歸,優點是效率更高且避免堆疊溢出,缺點是程式碼可能更複雜。選擇遞歸或非遞歸取決於問題和實現的特定限制。

改進的檢測演算法:用於高解析度光學遙感影像目標檢測 改進的檢測演算法:用於高解析度光學遙感影像目標檢測 Jun 06, 2024 pm 12:33 PM

01前景概要目前,難以在檢測效率和檢測結果之間取得適當的平衡。我們研究了一種用於高解析度光學遙感影像中目標偵測的增強YOLOv5演算法,利用多層特徵金字塔、多重偵測頭策略和混合注意力模組來提高光學遙感影像的目標偵測網路的效果。根據SIMD資料集,新演算法的mAP比YOLOv5好2.2%,比YOLOX好8.48%,在偵測結果和速度之間達到了更好的平衡。 02背景&動機隨著遠感技術的快速發展,高解析度光學遠感影像已被用於描述地球表面的許多物體,包括飛機、汽車、建築物等。目標檢測在遠感影像的解釋中

C++ 遞歸進階:瞭解尾遞歸最佳化及其應用 C++ 遞歸進階:瞭解尾遞歸最佳化及其應用 Apr 30, 2024 am 10:45 AM

尾遞歸最佳化(TRO)可提高特定遞歸呼叫的效率。它將尾遞歸呼叫轉換為跳轉指令,並將上下文狀態保存在暫存器中,而不是堆疊上,從而消除對堆疊的額外呼叫和返回操作,提高演算法效率。利用TRO,我們可以針對尾遞歸函數(例如階乘計算)進行最佳化,透過將tail遞歸呼叫替換為goto語句,編譯器會將goto跳轉移化為TRO,最佳化遞歸演算法的執行。

演算法在 58 畫像平台建置中的應用 演算法在 58 畫像平台建置中的應用 May 09, 2024 am 09:01 AM

一、58畫像平台建置背景首先和大家分享下58畫像平台的建造背景。 1.傳統的畫像平台傳統的想法已經不夠,建立用戶畫像平台依賴數據倉儲建模能力,整合多業務線數據,建構準確的用戶畫像;還需要數據挖掘,理解用戶行為、興趣和需求,提供演算法側的能力;最後,還需要具備數據平台能力,有效率地儲存、查詢和共享用戶畫像數據,提供畫像服務。業務自建畫像平台和中台類型畫像平台主要區別在於,業務自建畫像平台服務單條業務線,按需定制;中台平台服務多條業務線,建模複雜,提供更為通用的能力。 2.58中台畫像建構的背景58的使用者畫像

C++ 函式遞歸詳解:遞迴在字串處理中的應用 C++ 函式遞歸詳解:遞迴在字串處理中的應用 Apr 30, 2024 am 10:30 AM

遞歸函數是一種在字串處理中反覆呼叫自身來解決問題的技術。它需要一個終止條件以防止無限遞歸。遞歸在字串反轉和回文檢查等操作中被廣泛使用。

See all articles