假設二叉樹中每個結點的值為單個字元, 設計一個演算法將一棵以二叉鏈方式儲存的二叉樹 b 轉換成對應的順序儲存結構 a。——含具體實現工程
假設二叉樹中每個結點的值為單個字元, 設計一個演算法將一棵以二叉鏈方式儲存的二叉樹 b 轉換成對應的順序儲存結構 a。——李春葆資料結構第五版第七章,P246,第十題
思路解析:
解:設二叉樹的順序儲存結構型別為SqBTree,先將順序儲存結構a中所有元素置為‘#’(表示空結點)。將b轉換成a的遞迴模型如下:
f(b,a,i) -> a[i]='#'; 當b=NULL
f(b,a,i) -> 由b結點data域值建立a[i]元素; f(b->lchild,a,2*i); f(b->rchild,a,2*i+1); 其他情況
呼叫方式為:f(b,a,1)(a的下標從1開始)。
對應的演算法如下:
void Ctree(BTNode *b,SqBTree a,int i)
{ if (b!=NULL)
{ a[i]=b->data;
Ctree(b->lchild,a,2*i);
Ctree(b->rchild,a,2*i+1);
}
else a[i]='#';
}
具體實現:
我用VC++6.0做的工程,共建了5個原始碼檔案,程式碼可訪問https://github.com/COCO5666/Date_Structure下載(Chapter07/Ch07_10)
vc6.0(完整綠色版)(支援XP、Win7、Win8、Win10)
https://blog.csdn.net/COCO56/article/details/84570964
LiBTree.h
這裡為了避免因重複包含LiBTree.h而造成結構體型別(LBTNode)重複定義的錯誤發生,使用了#ifndef語句:
#ifndef LiBTree_H
#define LiBTree_H
//程式碼段
#endif
上面這句話的意思是如果沒有定義過LiBTree_H那麼定義LiBTree_H並執行"程式碼段",如果已經定義過則會跳過下面的所有語句,#endif用於結束條件編譯,編譯時與前面最近的#if、#ifdef或#ifndef作為一對,經常一起使用,來進行判斷是否編譯兩者之間的部分程式碼段(或稱程式段)。
#ifndef LiBTree_H
#define LiBTree_H
#include <cstdio>
#include <malloc.h>
#define ElemType char
#define MaxSize 500
typedef struct node
{
ElemType data;
struct node *lchild;
struct node *rchild;
}LBTNode;
void CreateLiBTree(LBTNode *&b, char *str);
void DispLiBTree(LBTNode *b);
void DestroyLiBTree(LBTNode *&b);
#endif
SqBTree.h
#include "LiBTree.h"
#include <cstdio>
#include <iostream>
using namespace std;
#define ElemType char
#define MaxSize 500
typedef ElemType SBTree[MaxSize];
typedef ElemType SBTNode;
void CreateSqBTFromLiBT(SBTNode *&SB, LBTNode *LB, int index=1);
void CreateSqBTree(SBTNode *&b, char *str);
void DispSqBTree(SBTNode *b, int index=1);
void DestroySqBTree(SBTNode *b);
LiBTree.cpp
#include "LiBTree.h"
void CreateLiBTree(LBTNode *&b, char *str)
{
LBTNode *St[MaxSize], *p;
int top=-1,k,j=0;
char ch;
b = NULL;
ch = str[j];
while(ch!='\0')
{
switch(ch)
{
case '(':top++;St[top]=p;k=1;break;
case ')':top--;break;
case ',':k=2;break;
default:p=(LBTNode *)malloc(sizeof(LBTNode));
p->data=ch;
p->lchild=p->rchild=NULL;
if(b==NULL)
{
b=p;
}
else
{
switch(k)
{
case 1:St[top]->lchild=p;break;
case 2:St[top]->rchild=p;break;
}
}
}
j++;
ch=str[j];
}
}
void DispLiBTree(LBTNode *b)
{
if(b!=NULL)
{
printf("%c", b->data);
if(b->lchild!=NULL || b->rchild!=NULL)
{
printf("(");
DispLiBTree(b->lchild);
if(b->rchild!=NULL)
{
printf(",");
}
DispLiBTree(b->rchild);
printf(")");
}
}
}
void DestroyLiBTree(LBTNode *&b)
{
if(b!=NULL)
{
DestroyLiBTree(b->lchild);
DestroyLiBTree(b->rchild);
free(b);
}
}
SqBTree.cpp
#include "SqBTree.h"
void CreateSqBTFromLiBT(SBTNode *&SB, LBTNode *LB, int index)
{
static bool flag = true;
if(flag)
{
SB = (SBTNode *)malloc(sizeof(SBTree));
flag = false;
for(int j=0; j<MaxSize; j++)
{
SB[j]='#';
}
}
if(LB!=NULL)
{
SB[index-1] = LB->data;
CreateSqBTFromLiBT(SB, LB->lchild, 2*index);
CreateSqBTFromLiBT(SB, LB->rchild, 2*index+1);
}
else
{
SB[index] = '#';
}
}
void CreateSqBTree(SBTNode *&b, char *str)
{
b = (SBTNode *)malloc(sizeof(SBTree));
int j=0, index=1;
for(;j<MaxSize;j++)
{
b[j]='#';
}
j=0;
char ch;
ch = str[j];
while(ch!='\0')
{
switch(ch)
{
case '(':index=index*2;break;
case ')':index=index/2;break;
case ',':index=index+1;break;
default:
b[index-1]=ch;break;
}
j++;
ch=str[j];
}
}
void DispSqBTree(SBTNode *b, int index)
{
if(b[index-1]!='#')
{
printf("%c", b[index-1]);
if(b[2*index-1]!='#' || b[2*index] !='#')
{
printf("(");
DispSqBTree(b, 2*index);
if(b[2*index] != '#')
printf(",");
DispSqBTree(b, 2*index+1);
printf(")");
}
}
}
void DestroySqBTree(SBTNode *b)
{
if(b!=NULL)
{
free(b);
b = NULL;
}
}
mian.cpp
#include "LiBTree.h"
#include "SqBTree.h"
#include "string.h"
#include <iostream>
using namespace std;
int main()
{
char str[]="A(B,C)";
int i;
SBTNode *SB, *SB2;
LBTNode *LB;
CreateLiBTree(LB, str);
DispLiBTree(LB);
cout << endl;
CreateSqBTree(SB, str);
for(i=0; i<10; i++)
cout << SB[i];
cout << endl;
DispSqBTree(SB);
cout << endl;
CreateSqBTFromLiBT(SB2, LB);
for(i=0; i<10; i++)
cout << SB2[i];
cout << endl;
DispSqBTree(SB2);
cout << endl;
DestroyLiBTree(LB);
DestroySqBTree(SB);
DestroySqBTree(SB2);
return 0;
}
相關文章
- 【資料結構】二叉樹(順序儲存、鏈式儲存)的JAVA程式碼實現資料結構二叉樹Java
- 二叉樹的儲存結構二叉樹
- C#資料結構-二叉樹-順序儲存結構C#資料結構二叉樹
- 二叉樹(順序儲存二叉樹,線索化二叉樹)二叉樹
- 二叉連結串列儲存結構、二叉樹相關操作二叉樹
- 資料結構-二叉樹的儲存結構與遍歷資料結構二叉樹
- 資料結構之樹結構概述(含滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹、紅黑樹、B-樹、B+樹、B*樹)資料結構二叉樹
- Kotlin 鏈式儲存的二叉樹中查詢節點Kotlin二叉樹
- 交換二叉樹中每個結點的左孩子和右孩子二叉樹
- 【資料結構虛擬碼】設計判斷一棵二叉樹是否是二叉排序樹的演算法資料結構二叉樹排序演算法
- [資料結構] 樹、二叉樹、森林的轉換資料結構二叉樹
- 二叉樹的儲存(輸入一串字元)與遍歷二叉樹字元
- 資料結構實驗之二叉樹八:(中序後序)求二叉樹的深度資料結構二叉樹
- Kotlin 鏈式儲存的二叉樹的建立、遍歷Kotlin二叉樹
- 演算法題(三十五):二叉樹的下一個結點演算法二叉樹
- 面試8:找二叉樹的下個結點面試二叉樹
- 資料結構中的樹(二叉樹、二叉搜尋樹、AVL樹)資料結構二叉樹
- 《劍指offer》:[58]二叉樹的下一個結點二叉樹
- 一本正經的聊資料結構(5):二叉樹的儲存結構與遍歷資料結構二叉樹
- 二叉樹中最遠的兩個結點的距離二叉樹
- 二叉樹的子結構、深度以及重建二叉樹二叉樹
- 串的順序儲存結構
- 樹的學習——樹的儲存結構
- 小結:二叉樹的幾種實現方式二叉樹
- 順序結構儲存串實現串萬用字元匹配的演算法字元演算法
- 二叉樹的子結構二叉樹
- 一個簡單的學生成績管理程式(二叉樹實現) (轉)二叉樹
- 佇列的順序儲存結構佇列
- 將二叉排序樹BST轉換成排序的雙向連結串列排序
- 008,二叉樹的下一個節點二叉樹
- 二叉搜尋樹的結構
- 二叉樹遍歷順序與方法小結二叉樹
- 資料結構(樹):二叉樹資料結構二叉樹
- 資料結構-二叉搜尋樹的實現資料結構
- SDUTOJ 2128 樹結構練習——排序二叉樹的中序遍歷排序二叉樹
- 二叉樹中兩個節點的最低公共祖先二叉樹
- 二叉樹兩個節點的公共節點二叉樹
- 線性結構(順序儲存和鏈式儲存)和非線性結構的特點及區別