一般树形结构 孩子链存储结构 孩子兄弟链存储结构 树的递归创建 求高度 输出 销毁

在学数据结构教程,参照书中对于节点结构体的定义,尝试用自己的思路递归实现,算是原创。
使用了模板、内联函数等等C++特性,因为想用。

/**
Ver 1. All Original
CreateTree in Recursion as all other func.
CreateTree Input: char s[] as para of func.

Func named "xxxxFunc()" is for other func to call, 
DO NOT CALL "xxxxFunc()" directly;
Use "xxxx()" instead.
*/
#include <iostream>
#include <cstdlib>  // malloc()
#include <algorithm>    // max()
using namespace std;
const int MAXSONS = 10;
const int MAXLEN = 100;
typedef char ElemType;
struct TSonNode {
    ElemType data;
    TSonNode* sons[MAXSONS];
};
struct TSBroNode {
    ElemType data;
    TSBroNode* hb;  // Horizonal bro
    TSBroNode* vs;  // Vertical son
};

ElemType str[MAXLEN];
int n=0;    // Extern. Uses as str[n].

// A Tree looks like 1. "A", 2. "A(B)", 3. "A(B, C)"
// if no '(' then tree is 1.
// catch B, if find ',' after B, tree is 3.
// else tree is 2.
void MakeTreeFunc(TSonNode*& T, ElemType* s) {
    int k=0;    // T->sons[k]
    T = (TSonNode*)malloc(sizeof(TSonNode));
    T->data = s[n++];
    for (int i=0; i<MAXSONS; ++i)
        T->sons[i] = NULL;
    if (s[n] == '(') {
        n++;    // n always points to a data before MakeTree
        MakeTreeFunc(T->sons[k++], s);
        while (s[n] == ',') {
            n++;
            MakeTreeFunc(T->sons[k++], s);
        }
        n++;    // skips ')'
    }
}
void MakeTreeFunc(TSBroNode*& T, ElemType* s) {
    T = (TSBroNode*)malloc(sizeof(TSBroNode));
    T->data = s[n++];
    T->hb = T->vs = NULL;
    if (s[n] == '(') {
        n++;
        MakeTreeFunc(T->vs, s);
    }
    if (s[n] == ',') {
        n++;
        MakeTreeFunc(T->hb, s);
    }   // As a node has only 2 links, more of ',' is for his bros.
    else n++;   // if not ',' then s[n] is ')', skip.
}
// Template to accept TSonNode or TSBroNode, re-init n=0;
template <typename F>
inline F* MakeTree(F*& T, ElemType* s) { MakeTreeFunc(T, s); n=0; return T; }
// default: create by TSonNode
inline TSonNode* MakeTree(ElemType* s) { 
    TSonNode* T;
    MakeTreeFunc(T, s);
    n=0;
    return T; 
}

// A Tree looks like 1. "A", 2. "A(B)", 3. "A(B, C)"
// always cout "A"
// if no son then tree is 1.
// else disp each son-tree.
// (son1, son2, ..., sonk)
void DispTreeFunc(TSonNode* T) {
    if (T == NULL) return;
    cout << T->data;
    int k=0;
    if (T->sons[k] != NULL) {
        cout << '(';
        while (1) {
            DispTreeFunc(T->sons[k++]);
            if (T->sons[k] == NULL)
                break;
            if (k < MAXSONS) cout << ',';
            else break;
        }
        cout << ')';
    }
}
// One node 2 links only
// Has son? Has h-bro?
void DispTreeFunc(TSBroNode* T) {
    if (T == NULL) return;
    cout << T->data;
    if (T->vs != NULL) {
        cout << '(';
        DispTreeFunc(T->vs);
        cout << ')';
    }
    if (T->hb != NULL) {
        cout << ',';
        DispTreeFunc(T->hb);
    }
}
template <typename F>
inline void DispTree(F* T) { DispTreeFunc(T); cout<<endl; }


int TreeHeight(TSonNode* T) {
    if (T == NULL) return 0;
    int ans = 0;
    for (int k=0; k<MAXSONS; ++k) {
        if (T->sons[k] == NULL) break;
        ans = max(ans, TreeHeight(T->sons[k]));
    }
    return ans + 1; // parent = MaxAmongSons + 1
}
int TreeHeight(TSBroNode* T) {
    if (T == NULL) return 0;
    int ans = 1;
    if (T->vs != NULL) {
        ans = TreeHeight(T->vs) + 1;    // parent = son + 1
    }
    if (T->hb != NULL) {    // son = MaxAmongBros
        ans = max(ans, TreeHeight(T->hb));
    }
    return ans;
}

void DestroyTree(TSonNode*& T) {
    if (T == NULL) return;
    for (int i=0; i<MAXSONS; ++i) {
        if (T->sons[i] != NULL)
            DestroyTree(T->sons[i]);
        else break;
    }
    free(T);
}
void DestroyTree(TSBroNode*& T) {
    if (T == NULL) return;
    if (T->hb != NULL) DestroyTree(T->hb);
    if (T->vs != NULL) DestroyTree(T->vs);
    free(T);
}

int main()
{
    TSonNode* pts = NULL;
    TSBroNode* ptsb = NULL;
    cin >> str;
    
    DispTree(MakeTree(pts, str));       // MakeTree returns Node*
    cout << TreeHeight(pts) << endl;

    DispTree(MakeTree(str));            // Makes TSonNode Tree without pts para

    MakeTree(ptsb, str);    // Using Template to shift between NodeType
    DispTree(ptsb);
    cout << TreeHeight(ptsb) << endl;
    return 0;
}
/*
A(B(E,F),C(G(J)),D(H,I(K(N,O),L,M)))
>>>5
A(B,C(F,G,H),D,E(I,J))
>>>3
*/

第二个版本,前三个函数是不同的,后两个是书上的做法部分替换为STL的实现。整体上,采用了键盘输入,而不是第一版的从字符串传参数。

/*
Ver 2. Book-referred
The First 3 func are new to ver 1.
CreateTree with stack.
CreateTree Input: cin.get() from Keyboard,
therefore you can only create one tree at one input.

Func named "xxxxFunc()" is for other func to call, 
DO NOT CALL "xxxxFunc()" directly;
Use "xxxx()" instead.
*/
#include <iostream>
#include <cstdlib>  // malloc()
#include <algorithm>
#include <stack>
#include <utility>  // pair, make_pair()
using namespace std;
const int MAXSONS = 10;
const int MAXLEN = 100;
typedef char ElemType;
struct TSonNode {
    ElemType data;
    TSonNode* sons[MAXSONS];
};
struct TSBroNode {
    ElemType data;
    TSBroNode* hb;
    TSBroNode* vs;
};
// Recursion as ver 1.
// But substitute cin.get() for a char str[]
// Advantage: avoid external para int n. 
void MakeTree_R(TSonNode*& T) {
    int k=0;
    T = (TSonNode*)malloc(sizeof(T));
    T->data = cin.get();
    for (int i=0; i<MAXSONS; ++i)
        T->sons[i] = NULL;
    if (cin.peek() == '(') {
        cin.get();
        MakeTree_R(T->sons[k++]);
        while (cin.peek() == ',') {
            cin.get();
            MakeTree_R(T->sons[k++]);
        }
        cin.get();
    }
}
TSonNode* MakeTree(TSonNode*& T) {
    T = NULL;
    TSonNode* p = NULL;
    stack<pair<TSonNode*, int> > st;    // == stack<struct node>
    ElemType ch;
    while ((ch = cin.get()) != '\n') {
        switch (ch)
        {
        case '(':
            st.push(make_pair(p, 0));
            break;
        case ',':
            st.top().second++;
            break;
        case ')':
            st.pop();
            break;
        default:
            p = (TSonNode*)malloc(sizeof(TSonNode));
            p->data = ch;
            for (int i=0; i<MAXSONS; ++i) {
                p->sons[i] = NULL;
            }
            if (T == NULL) T = p;   // get first data
            else st.top().first->sons[st.top().second] = p; // then always possess top node
            break;
        }
    }
    return T;
}
TSBroNode* MakeTree(TSBroNode*& T) {
    T = NULL;   
    TSBroNode* p = NULL;
    stack<pair<TSBroNode*, int> > st;   
    ElemType ch;
    while ((ch = cin.get()) != '\n') {
        switch (ch)
        {
        case '(':
            st.push(make_pair(p, 0));
            break;
        case ',':
            st.top().second++;
            break;
        case ')':
            st.pop();
            break;
        default:
            p = (TSBroNode*)malloc(sizeof(TSBroNode));
            p->data = ch;
            p->vs = NULL;
            p->hb = NULL;
            if (T == NULL) T = p;
            else if (st.top().second == 0) {
                st.top().first->vs = p;
            } else {
                TSBroNode* q = st.top().first->vs;
                for (int i=1; i<st.top().second; i++) {
                    q = q->hb;
                }   //q moves SonNum - 1 rightward, to be left to p.
                q->hb = p;
            }
            break;
        }
    }
    return T;
}
void DispTreeFunc(TSonNode* T) {
    if (T == NULL) return;
    cout << T->data;
    int k=0;
    if (T->sons[k] != NULL) {
        cout << '(';
        while (1) {
            DispTreeFunc(T->sons[k++]);
            if (T->sons[k] == NULL)
                break;
            if (k < MAXSONS) cout << ',';
            else break;
        }
        cout << ')';
    }
}
void DispTreeFunc(TSBroNode* T) {
    if (T == NULL) return;
    cout << T->data;
    if (T->vs != NULL) {
        cout << '(';
        DispTreeFunc(T->vs);
        cout << ')';
    }
    if (T->hb != NULL) {
        cout << ',';
        DispTreeFunc(T->hb);
    }
}
template <typename F>
inline void DispTree(F* T) { DispTreeFunc(T); cout<<endl; }


int TreeHeight(TSonNode* T) {
    if (T == NULL) return 0;
    int ans = 0;
    for (int k=0; k<MAXSONS; ++k) {
        if (T->sons[k] == NULL) break;
        ans = max(ans, TreeHeight(T->sons[k]));
    }
    return ans + 1;
}
int TreeHeight(TSBroNode* T) {
    if (T == NULL) return 0;
    int ans = 1;
    if (T->vs != NULL) {
        ans = TreeHeight(T->vs) + 1;
    }
    if (T->hb != NULL) {
        ans = max(ans, TreeHeight(T->hb));
    }
    return ans;
}

void DestroyTree(TSonNode*& T) {
    if (T == NULL) return;
    for (int i=0; i<MAXSONS; ++i) {
        if (T->sons[i] != NULL)
            DestroyTree(T->sons[i]);
        else break;
    }
    free(T);
}
void DestroyTree(TSBroNode*& T) {
    if (T == NULL) return;
    if (T->hb != NULL) DestroyTree(T->hb);
    if (T->vs != NULL) DestroyTree(T->vs);
    free(T);
}
int main()
{
    TSonNode* pst = NULL;
    TSBroNode* psbt = NULL;
    // MakeTree(pt);
    // // DispTree(pt);
    // MakeTree(pst);
    // DispTree(pst);
    // DestroyTree(pst);

    MakeTree(psbt);
    DispTree(psbt);
    cout << TreeHeight(psbt) << endl;
    DestroyTree(psbt);
    return 0;
}
/*
A(B(E,F),C(G(J)),D(H,I(K,L,M)))
>>>4
*/

参考:《数据结构教程》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值