最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一波二叉樹遍歷問題的C++解答實(shí)例分享

 更新時(shí)間:2016年02月15日 16:29:43   作者:Zhang_H  
這篇文章主要介紹了一波二叉樹遍歷問題的C++解答實(shí)例分享,包括節(jié)點(diǎn)打印和轉(zhuǎn)換為鏡像等問題的解答,需要的朋友可以參考下

題目一:

  輸入一顆二元樹,從上往下按層打印樹的每個節(jié)點(diǎn),同一層按照從左往右的順序打印。

輸入樣例:

 8

 / /

 6 10

/ / / /

5 7 9 11

輸出樣例:

復(fù)制代碼 代碼如下:
8 6 10 5 7 9 11

思路分析:

    把一顆二叉樹抽象成三個節(jié)點(diǎn):根節(jié)點(diǎn)、左節(jié)點(diǎn)、右節(jié)點(diǎn)。

    先序遍歷即可得到按行輸出的效果。

    對于左子樹只要保存其根節(jié)點(diǎn),既保存了整個左子樹。(右子樹一樣)

    對于根節(jié)點(diǎn)之外的兩個子樹來說說,始終是先訪問左子樹的根節(jié)點(diǎn),再訪問右子樹的根節(jié)點(diǎn)。

    因此可以使用隊(duì)列存儲。

代碼實(shí)現(xiàn)(GCC編譯通過):

#include "stdio.h"
#include "stdlib.h"
 
//二叉樹節(jié)點(diǎn)
#define size 7
 
//二叉樹節(jié)點(diǎn)定義
typedef struct node
{
  int data;
  struct node *left;
  struct node *right;
}BTree;
 
int printLine(BTree * root);
BTree * CreatTree(int a[],int n);
 
int main(void)
{
 
    int array[size] = {8,6,10,5,7,9,11};
    BTree * root;
 
    root = CreatTree(array,size);
  printLine(root);  
 
    printf("\n");
  return 0;
}
 
int printLine(BTree * root)
{
  BTree * queue[size], *p;
  int front,rear;
  front = rear = 0;
   
   
   
  rear = (rear+1)%size;
  queue[rear] = root;  
 
    //循環(huán)結(jié)束為隊(duì)列為空
  while(front != rear)
  {    
      //根出隊(duì)列
    front = (front +1)%size;
    p = queue[front];
    printf("%3d",p->data);
 
    //左孩子不空,隊(duì)不滿入隊(duì)
    if(p->left && ((rear+1)%size != front))
    {
      rear = (rear+1)%size;
      queue[rear] = p->left;
    }
         
        //右孩子不空,隊(duì)不滿入隊(duì)
    if(p->right && ((rear+1)%size != front))
    {
      rear = (rear+1)%size;
      queue[rear] = p->right;
    }
         
        //隊(duì)滿,報(bào)錯
    if((rear+1)%size == front)
    {
      printf("隊(duì)列空間不足,錯誤....\n");
      return 0;
    }
  }
 
  return 1;
}
 
//根據(jù)數(shù)組創(chuàng)建二叉排序樹
BTree * CreatTree(int a[],int n)
{
    BTree * root ,*p,*cu,*pa;
    int i;
 
    root = (BTree *)malloc(sizeof(BTree));
    root->data = a[0];
    root->left = root->right =NULL;
 
    for(i=1;i<n;i++)
    {
        p = (BTree *)malloc(sizeof(BTree));
        p->data = a[i];
        p->left = p->right =NULL;
        cu = root;
 
        while(cu)
        {
            pa = cu;
            if(cu->data > p->data)
                cu = cu->left;
            else
                cu = cu->right;
        }
        if(pa->data > p->data)
            pa->left = p;
        else
            pa->right = p;
    }
 
    return root;
}

題目二:

輸入一個整數(shù)數(shù)組,判斷該數(shù)組是不是某二元查找樹的后序遍歷的結(jié)果。

如果是返回 true,否則返回 false。

例如輸入 5、7、6、9、11、10、8,由于這一整數(shù)序列是如下樹的后序遍歷結(jié)果:

8

/  \

6  10

/  \  /  \

5  7  9  11

因此返回 true。

如果輸入 7、4、6、5,沒有哪棵樹的后序遍歷的結(jié)果是這個序列,因此返回 false。

思路:

二叉查找的特征:左子樹的各個值均小于根,右子樹的各個值均大于跟

后序遍歷的特征:最后一個是根,便利順序,左右跟。遞歸

好了,總結(jié)可以得到:

最后一個是根,最開始連續(xù)若干個數(shù)小于根的是左子樹的節(jié)點(diǎn),之后連續(xù)若干個大于根的是右子樹的節(jié)點(diǎn)(左右子樹都可能為空),然后遞歸描述。

代碼描述如下(GCC編譯通過):

#include "stdio.h"
#include "stdlib.h"
 
int isPostorderResult(int a[],int n);
int helper(int a[],int s,int e);
 
int main(void)
{
  int a[7] = {5,7,6,9,11,10,8};
  int b[4] = {7,4,6,5};
  int tmp;
 
  tmp = isPostorderResult(a,7);
  printf("%d",tmp);
 
  return 0;
}
 
 
 
int isPostorderResult(int a[],int n)
{
  return helper(a,0,n-1);
}
 
int helper(int a[],int s,int e)
{
  int i,j,root;
   
  if(s == e)
    return 1; 
 
  for(i=0;i<e && a[i]<a[e];i++);
  if(i != 0 && helper(a,s,i-1) == 0)
    return 0;
 
  for(j=i;j<e && a[j]>a[e];j++);
  if(j==e && helper(a,i,j-1) == 1)
    return 1;
  else
    return 0;
   
   
}

題目三:

輸入一顆二元查找樹,將該樹轉(zhuǎn)換為它的鏡像,即在轉(zhuǎn)換后的二元查找樹中,左子樹的結(jié)點(diǎn)都大于右子樹的結(jié)點(diǎn)。
用遞歸和循環(huán)兩種方法完成樹的鏡像轉(zhuǎn)換。
例如輸入:

8
/ \
6 10
/\ /\
5 7 9 11

輸出:

    8
  /     \
  10     6
  /\       /\
11   9   7   5

分析:

遞歸程序設(shè)計(jì)比較簡單

    訪問一個節(jié)點(diǎn),只要不為空則交換左右孩子,然后分別對左右子樹遞歸。

非遞歸實(shí)質(zhì)是需要我們手動完成壓棧,思想是一致的

代碼如下(GCC編譯通過):

#include "stdio.h"
#include "stdlib.h"
 
#define MAXSIZE 8
 
typedef struct node
{
  int data;
  struct node * left;
  struct node * right;
}BTree;
 
void swap(BTree ** x,BTree ** y);//交換左右孩子
void mirror(BTree * root);//遞歸實(shí)現(xiàn)函數(shù)聲明
void mirrorIteratively(BTree * root);//非遞歸實(shí)現(xiàn)函數(shù)聲明
BTree * CreatTree(int a[],int n);//創(chuàng)建二叉樹(產(chǎn)生二叉排序樹)
void Iorder(BTree * root);//中序遍歷查看結(jié)果
 
int main(void)
{
  int array[MAXSIZE] = {5,3,8,7,2,4,1,9};
  BTree * root;
 
  root = CreatTree(array,MAXSIZE);
 
  printf("變換前:\n");
  Iorder(root);
 
  printf("\n變換后:\n");//兩次變換,與變化前一致
  mirror(root);
  mirrorIteratively(root);
  Iorder(root);
 
 
 
  printf("\n");
 
  return 0;
}
 
void swap(BTree ** x,BTree ** y)
{
  BTree * t = * x;
  * x = * y;
  * y = t;
}
 
void mirror(BTree * root)
{
  if(root == NULL)//結(jié)束條件
    return;
   
  swap(&(root->left),&(root->right));//交換
  mirror(root->left);//左子樹遞歸
  mirror(root->right);//右子樹遞歸
}
 
void mirrorIteratively(BTree * root)
{
  int top = 0;
  BTree * t;
  BTree * stack[MAXSIZE+1];
   
  if(root == NULL)
    return;
 
  //手動壓棧、彈棧
  stack[top++] = root;
  while(top != 0)
  {
    t = stack[--top];   
    swap(&(t->left),&(t->right));
 
    if(t->left != NULL)
      stack[top++] = t->left;
    if(t->right != NULL)
      stack[top++] = t->right;
  }
}
 
//產(chǎn)生二叉排序樹
BTree * CreatTree(int a[],int n)
{
  BTree * root ,*p,*cu,*pa;
  int i;
   
  root = (BTree *)malloc(sizeof(BTree));
  root->data = a[0]; 
  root->left = root->right =NULL;
 
  for(i=1;i<n;i++)
  {
    p = (BTree *)malloc(sizeof(BTree));
    p->data = a[i];
    p->left = p->right =NULL;
    cu = root;
 
    while(cu)
    {
      pa = cu;
      if(cu->data > p->data)
        cu = cu->left;
      else
        cu = cu->right;
    }
    if(pa->data > p->data)
      pa->left = p;
    else
      pa->right = p;
  }  
 
  return root;
}
//中序遍歷
void Iorder(BTree * root)
{
  if(root)
  {    
    Iorder(root->left);
    printf("%3d",root->data);
    Iorder(root->right);
  }
}

相關(guān)文章

  • Qt槽函數(shù)會被執(zhí)行多次的問題原因及解決方法

    Qt槽函數(shù)會被執(zhí)行多次的問題原因及解決方法

    本文主要介紹了Qt槽函數(shù)會被執(zhí)行多次的問題原因及解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • C語言算法打卡回文串驗(yàn)證算法題解

    C語言算法打卡回文串驗(yàn)證算法題解

    這篇文章主要為大家介紹了C語言算法打卡萬人千提的leetcode回文串的驗(yàn)證算法題解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • C數(shù)據(jù)結(jié)構(gòu)循環(huán)鏈表實(shí)現(xiàn)約瑟夫環(huán)

    C數(shù)據(jù)結(jié)構(gòu)循環(huán)鏈表實(shí)現(xiàn)約瑟夫環(huán)

    這篇文章主要介紹了C數(shù)據(jù)結(jié)構(gòu)循環(huán)鏈表實(shí)現(xiàn)約瑟夫環(huán)的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++中 set的用法

    C++中 set的用法

    這篇文章主要介紹了C++中 set的用法,set的內(nèi)部使用了紅黑樹對所有的元素進(jìn)行了排序。在樹結(jié)構(gòu)當(dāng)中,我們通常使用的都是<key, value>的形式。下面我們來看看該內(nèi)容的具體情況,需要的朋友也可以參考一下
    2021-11-11
  • C++11 std::function和std::bind 的使用示例詳解

    C++11 std::function和std::bind 的使用示例詳解

    C++11中的std::function和std::bind是函數(shù)對象的重要組成部分,它們可以用于將函數(shù)和參數(shù)綁定在一起,形成一個可調(diào)用的對象,這篇文章主要介紹了C++11 std::function和std::bind 的使用示例詳解,需要的朋友可以參考下
    2023-03-03
  • C++?構(gòu)造函數(shù)學(xué)習(xí)筆記

    C++?構(gòu)造函數(shù)學(xué)習(xí)筆記

    這篇文章主要為大家介紹了C++?構(gòu)造函數(shù)學(xué)習(xí)筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • C語言中find_package()的搜索路徑的實(shí)現(xiàn)

    C語言中find_package()的搜索路徑的實(shí)現(xiàn)

    本文主要介紹了C語言中find_package()的搜索路徑的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • C語言實(shí)現(xiàn)隨機(jī)發(fā)牌

    C語言實(shí)現(xiàn)隨機(jī)發(fā)牌

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)隨機(jī)發(fā)牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C++中string字符串分割函數(shù)split()的4種實(shí)現(xiàn)方法

    C++中string字符串分割函數(shù)split()的4種實(shí)現(xiàn)方法

    最近筆試經(jīng)常遇到需要對字符串進(jìn)行快速分割的情景,下面這篇文章主要給大家介紹了關(guān)于C++中string字符串分割函數(shù)split()的4種實(shí)現(xiàn)方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • 歸并排序的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)代碼

    歸并排序的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)代碼

    以下是對歸并排序的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下
    2013-08-08

最新評論

托里县| 惠东县| 唐山市| 同心县| 临城县| 舟曲县| 衡东县| 明光市| 当雄县| 苏尼特左旗| 上犹县| 奎屯市| 荔浦县| 乐东| 汕头市| 固原市| 富平县| 长岭县| 茶陵县| 聂拉木县| 响水县| 凤凰县| 巩留县| 丹巴县| 师宗县| 岫岩| 广丰县| 景德镇市| 桐城市| 金坛市| 宜黄县| 新干县| 基隆市| 保亭| 烟台市| 随州市| 万载县| 都安| 吴忠市| 遂平县| 桦南县|