機(jī)試常用算法和題型-樹專題

靜態(tài)創(chuàng)建新結(jié)點、構(gòu)造二叉樹實現(xiàn)前序中序遍歷還原

#include <iostream>
#include <string>
using namespace std;

//復(fù)原二叉樹,。想出算法,

//靜態(tài)版,遞歸的邊界條件和遞歸式由str1的s1,e1,str2的s2,e2聯(lián)合確定,縮小開頭和結(jié)尾劃分子問題

struct Node{
    char data;
    Node *rchild;
    Node *lchild;
}Tree[50];

//靜態(tài)如何創(chuàng)建新節(jié)點,就是loc游標(biāo)移動
int loc;
Node *create(){
    Tree[loc].lchild=Tree[loc].rchild=NULL;
    //返回的是指針
    return &Tree[loc++];
}
string str1,str2;
//在函數(shù)當(dāng)中就要用到,提前定義
Node *build(int s1,int e1,int s2,int e2){
    //直接每個都要創(chuàng)建新節(jié)點的??!我傻了
    Node *ret=create();
    ret->data=str1[s1];
    int rootIdx=str2.find(str1[s1]);
    //找到根節(jié)點在str2中的位置
    //遞歸邊界+遞歸式
    if(rootIdx!=s2){
        //左子樹不為空
        ret->lchild=build(s1+1,s1+(rootIdx-s2),s2,rootIdx-1);
        //邊界的確定最難了
    }
    if(rootIdx!=e2){
        ret->rchild=build(s1+(rootIdx-s2)+1,e1,rootIdx+1,e2);
    }
    return ret;
}
//動態(tài)創(chuàng)建的辦法,以及帶出口邊界的寫法
node * create(int preL,int preR,int inL,int inR)
{
    if(preL>preR)
        return NULL;
    node * p=new node;
    p->data=pre[preL];
    int k;
    for(k=inL;k<inR;++k)
        if(in[k]==pre[preL])
            break;
    int numleft=k-inL;
    p->lchild=create(preL+1,preL+numleft,inL,k-1);
    p->rchild=create(preL+numleft+1,preR,k+1,inR);
    return p;
}


void postOrder(Node *r){
    //遍歷出口
    if(r==NULL){
        return;
    }
    postOrder(r->lchild);
    postOrder(r->rchild);
    printf("%c",r->data);
}
int main()
{
    while(cin>>str1>>str2){
        Node *T;
        int e1=str1.size()-1;
        int e2=str2.size()-1;
        T=build(0,e1,0,e2);
        postOrder(T);
        printf("\n");
    }
    return 0;
}

二叉排序樹查找、插入、構(gòu)造科學(xué)方法

7
8 6 5 7 10 8 11

#include <iostream>
#include <vector>
using namespace std;

struct node{
    int data;
    node *rchild;
    node *lchild;
};

//創(chuàng)建新結(jié)點還是要寫一個,這樣的話,才可以創(chuàng)建空結(jié)點,類似于鏈表知道到了鏈表尾部
node *newNode(int x){
    node *Node=new node;
    Node->data=x;
    Node->rchild=Node->lchild=NULL;
    return Node;
}

//如何構(gòu)造二叉排序樹
//有無到有,其實就是n次插入,而插入其實是查找的更進(jìn)一步,找到空的位置?。?
void insL(node *&root,int x)
{
    //次數(shù)一定要加上引用,因為root結(jié)構(gòu)發(fā)生了變化
    if(root==NULL) {
            //定義出口,空結(jié)點的位置創(chuàng)建新點
        root=newNode(x);
        return;
    }
    //原因在這里,相等時也可以插
 /*   if(x==root->data){
        return;
        //查找結(jié)點,如果發(fā)現(xiàn)這個結(jié)點被插入,就不用二次插入
    }else if(x<root->data){
        insL(root->lchild,x);
    }else {
        insL(root->rchild,x);
    }*/
    if(x<root->data) insL(root->lchild,x);
    else insL(root->rchild,x);
}
//數(shù)組參數(shù)如何處理



//換成高級寫法
void preOrder(node *T,vector<int> &vi){
    if(T==NULL) return;
    vi.push_back(T->data);
    preOrder(T->lchild,vi);
    preOrder(T->rchild,vi);
}

void postOrder(node *T,vector<int> &vi){
    if(T==NULL) return;

    postOrder(T->lchild,vi);
    postOrder(T->rchild,vi);
    vi.push_back(T->data);
}

void mirOrderPre(node *T,vector<int> &vi){
    if(T==NULL) return;
    vi.push_back(T->data);

    mirOrderPre(T->rchild,vi);
    mirOrderPre(T->lchild,vi);
}

void mirOrderPost(node *T,vector<int> &vi){
    if(T==NULL) return;

    mirOrderPost(T->rchild,vi);
    mirOrderPost(T->lchild,vi);
    vi.push_back(T->data);
}


vector<int> origin,pre,preM,post,postM;
int main()
{

    int n;
    while(cin>>n){

        node *T=NULL;
        for(int i=0;i<n;i++){
            int x;
            cin>>x;
            origin.push_back(x);
            //循環(huán)插入即可
            insL(T,x);
        }

        preOrder(T,pre);
        postOrder(T,post);
        mirOrderPre(T,preM);
        mirOrderPost(T,postM);
        //容器vector可以直接相等!!!
        if(origin==pre){
            cout<<"YES"<<endl;
            for(int i=0;i<post.size();i++){
                cout<<post[i]<<" ";
            }
        }else if(origin==preM){
             cout<<"YES"<<endl;
            for(int i=0;i<postM.size();i++){
                cout<<postM[i]<<" ";
            }
        }else{
        cout<<"NO"<<endl;
        }
        cout<<endl;
    }
    return 0;
}

二叉排序樹建立,非遞歸遍歷方法

/*第三題:輸入一個字符串,建立一個二叉排序樹,并中序遍歷輸出;*/
 
/*這里采用了兩種遍歷,此處是非遞歸。下面注釋的是遞歸*/
/*測試數(shù)據(jù): poiuyt    輸出數(shù)據(jù);i o p t u y   
  測試數(shù)據(jù): 621345     輸出數(shù)據(jù): 1 2 3 4 5 6*/
/*程序:*************************愛X的味道 07級華中農(nóng)業(yè)大學(xué)計算機(jī)系*****************************/
 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 50
typedef struct Node
{
    char data;
    struct Node *Lchild;
    struct Node *Rchild;
}Node,*BiTree;
 
typedef struct 
{
    BiTree elem[MAX];
    int top;
}Stack;  
void InitStack(Stack *s)
{
    s->top=-1;
}
int Push(Stack *s,BiTree *T)
{
    if(s->top>MAX-1) return 0;
    s->top++;
    s->elem[s->top]=(*T);
    return 1;
}
int Pop(Stack *s,BiTree *T)
{
    if(s->top<-1) return 0;
    *T=s->elem[s->top];   
    s->top--;
    return 1;
}
int IsEmpty(Stack s)
{
    if(-1==s.top)
        return 1;
    else
        return 0;
}
void InsertSortTree(BiTree *tree, char key)
{
    BiTree T;
    if(*tree == NULL)
    {
        T=(BiTree)malloc(sizeof(Node));
        T->data=key;
        T->Lchild=NULL;
        T->Rchild=NULL;
        *tree=T;
    }
    else
        if((*tree)->data>key)
            InsertSortTree(&((*tree)->Lchild),key);
        else
            if((*tree)->data<key)
                InsertSortTree(&((*tree)->Rchild),key);
}
void CreateSortTree(BiTree  *tree,char *str )
{
    *tree=NULL;
    int i=0;
    while(str[i]!='\0')
    {
        InsertSortTree(&(*tree),str[i]);
        i++;
    }
}
 
void InOrdTree(BiTree T)    
{
    Stack s;
    BiTree p=T;
    InitStack(&s);
    while(p!=NULL || !IsEmpty(s))
    {
        if(p!=NULL)
        {
            Push(&s,&p);
            p=p->Lchild;
        }
        else
        {
            Pop(&s,&p);
            printf(" %c ",p->data);
            p=p->Rchild;
        }
    }
    printf("\n\n");
}
int main()
{
    char str[100]="\0";
    BiTree tree;
    printf("請輸入一個字符串:\n\n");
    gets(str);
    CreateSortTree(&tree,str);
    printf("中序遍歷的結(jié)果是:\n\n");
    InOrdTree(tree);
    printf("\n\n");
    return 0;
}
 
/*
/*輸入一個字符串,建立一個二叉排序樹,并中序遍歷輸出;
要考慮字符串,好難

#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

typedef struct Node{
    int data;
    Node *lchild,*rchild;
}Node,*BiTree;

Node * creatNode(int data){
    Node *T=(Node*)malloc(sizeof(Node));
    if(T==NULL){
        exit(0);
    }
    T->data=data;
    T->lchild=NULL;
    T->rchild=NULL;
    return T;
}

//只有返回值時樹節(jié)點才node *好不好
int InsertNode(BiTree &T,int key){
    if(T==NULL){
        T=creatNode(key);
        return 1;
    }

    //應(yīng)當(dāng)要檢查要插入的是否已經(jīng)存在的,如果查找失敗直接插入,則p指向遍歷最后一個節(jié)點
    //主要是根據(jù)key找位置
    else if(key==T->data){
        return 0;
    }else if(key<T->data){
    return InsertNode(T->lchild,key);
    }else return InsertNode(T->rchild,key);
}

void inOrder(Node *T){
    if(T!=NULL){
        inOrder(T->lchild);
        printf("%c ",T->data);
        inOrder(T->rchild);
    }

}

int main(){
    Node *T=NULL;
    string str;
    cin>>str;
    for(int i=0;i<str.size();i++){
            //我錯了,strcpy(c,s.c_str()); 用在一整個串
        char c=str[i];
        InsertNode(T,c);

    }
    //這個怎么能在循環(huán)內(nèi)部呢.想看一下傳值里面是怎么變化的??!
    //剛才使用返回return,每次都返回當(dāng)前節(jié)點~~
    inOrder(T);
}
*/

無冗余字符串?dāng)?shù)組加建立二叉排序樹

#include<stdio.h>
#include<malloc.h>
#include<string.h>

typedef struct BiNode
{
    char *s;
    struct BiNode *lchild;
    struct BiNode *rchild;
}BiNode,*BiTree;

void PreOrder(BiTree T)
{
    if(T)
    {
        printf("%s\n",T->s);
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}
int main()
{
    char **str,e;
    int row=1,col=1;
    int tag,i,len;
    BiTree T,r,t;
    str=(char **)malloc(row*sizeof(char *));
    str[col-1]=(char *)malloc(col*sizeof(char));
    tag=1;
    while((e=getchar())!='\n')
    {
        if(e==' ')
        {
            str[row-1][col-1]='\0';
            tag=0;
            continue;
        }
        else
        {
            if(tag==0)
            {
                row++;
                col=2;
                str=(char **)realloc(str,row*sizeof(char *));
                str[row-1]=(char *)malloc(col*sizeof(char));
                str[row-1][col-2]=e;
                tag=1;
            }
            else
            {
                col++;
                str[row-1]=(char *)realloc(str[row-1],col*sizeof(char));
                str[row-1][col-2]=e;
            }
        }
    }
    str[row-1][col-1]='\0';
    for(i=0;i<row;i++)
        printf("%s\n",str[i]);
    printf("\n");

    len=strlen(str[0]);
    T=(BiTree)malloc(sizeof(BiNode));
    T->s=(char *)malloc((len+1)*sizeof(char));
    strcpy(T->s,str[0]);
    T->lchild=T->rchild=NULL;
    t=T;
    for(i=1;i<row;i++)
    {
        len=strlen(str[i]);
        r=(BiTree)malloc(sizeof(BiNode));
        r->s=(char *)malloc((len+1)*sizeof(char));
        r->lchild=NULL;
        r->rchild=NULL;
        strcpy(r->s,str[i]);
        while(t)
        {
            if(strcmp(t->s,r->s)>0)
            {
                if(t->lchild)
                    t=t->lchild;
                else
                {
                    t->lchild=r;
                    break;
                }
            }
            else
            {
                if(t->rchild)
                    t=t->rchild;
                else
                {
                    t->rchild=r;
                    break;
                }
            }
        }
        t=T;
    }
    PreOrder(T);
    return 0;
}

如何創(chuàng)建樹鏈表,進(jìn)行逆中序遍歷

/*輸入一個數(shù)列以0結(jié)尾,建立二叉遍歷數(shù),并對其進(jìn)行逆中序遍歷,釋放空間*/
/*(2)輸入一個數(shù)列以0位結(jié)束標(biāo)志,建立二叉遍歷樹,并對其進(jìn)行逆中序遍歷,釋放空間。*/
/*示例樹為 :             1    
                        /   \
                       2      3
                        \      \
                         4       5
                       /  \       \
                      6    7       8       每次輸入一個數(shù),按一次回車
   輸入的序列為 : 1 2 0 4 6 0 0 7 0 0 3 0 5 0 8 0 0  
   輸出的結(jié)果應(yīng)為: 8 5 3 1 7 4 6 2           */
————————————————

#include<stdio.h>
#include<stdlib.h>
typedef struct BiTNode{//二叉樹數(shù)據(jù)結(jié)構(gòu)定義;
    int data;
    BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

BiTree CreateTree(){//創(chuàng)建二叉樹;
    int value;
    BiTree t;
    scanf("%d",&value);
    if(value==0)return NULL;
    else{
         t=(BiTree)malloc(sizeof(BiTNode));
         t->data=value;
         t->lchild=CreateTree();
         t->rchild=CreateTree();
         return t;
    }
}

void ReInOrder(BiTree t){//逆中序遍歷二叉樹;
     if(t!=NULL){
          ReInOrder(t->rchild);
          printf("%d ",t->data);
          ReInOrder(t->lchild);
          free(t);
     }
}

int main(){
    BiTree t;
    printf("請按序輸入二叉樹結(jié)點的值(以0為標(biāo)志結(jié)束):\n");
    t=CreateTree();
    printf("逆中序遍歷二叉樹:\n");
    ReInOrder(t);
    system("pause");
}

//另一種寫法
#include <iostream>
#include <32/bits/stdc++.h>
using namespace std;

struct node{
    int data;
    node *lchild,*rchild;
};

//兩種方式,引用或者node *返回!??!
void insertT(node *&root){
    int x;
    cin>>x;
    if(x==0) return;
    if(root==NULL){
        //應(yīng)當(dāng)創(chuàng)建新結(jié)點
        root=new node;
        root->data=x;
        root->lchild=NULL;
        root->rchild=NULL;
    }
    //每個結(jié)點應(yīng)該都是空的,可以自己往下接s
    insertT(root->lchild);
    insertT(root->rchild);

}

void inOrdedr(node *root){
    if(root!=NULL){
        inOrdedr(root->rchild);
        cout<<root->data<<" ";
        inOrdedr(root->lchild);
    }

}


int main()
{

    node *T=NULL;
    insertT(T);
    inOrdedr(T);

    return 0;
}

后序加中序還原加層序遍歷

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

//后序加中序遍歷推出

#include <iostream>
#include <queue>
#include <string>
using namespace std;

struct node{
    int data;
    node *lchild;
    node *rchild;
};

int a[40],b[40];

node *build(int s1,int e1,int s2,int e2){
    //終于知道了?。]有創(chuàng)建新結(jié)點,咋個有空間放數(shù)據(jù)和指針
    if(s1>e1) return NULL;
    //啟示?。懛ㄒ涮?,不然會出現(xiàn)沒有NULL結(jié)點無法結(jié)束的情況
    node *newNode=new node;

    //后序遍歷最后一個結(jié)點為根結(jié)點
    newNode->data=a[e1];

    int i;
    for(i=s2;i<=e2;i++){
        if(b[i]==a[e1]) break;
    }
    int pos=i;

    int leftNum=pos-s2;

    //左子樹非空,構(gòu)建左子樹
    newNode->lchild=build(s1,s1+leftNum-1,s2,pos-1);
    newNode->rchild=build(s1+leftNum,e1-1,pos+1,e2);

    return newNode;
}

void preOrder(node *T){
    if(T==NULL) return;
    cout<<T->data<<" ";
    preOrder(T->lchild);
    preOrder(T->rchild);
}

void floor(node *T){
    queue<node*> q;
    //注意隊列當(dāng)中存放的是地址
    q.push(T);
    //while條件就出口
    while(!q.empty()){
        //取隊頭,出隊,訪問
            node *now=q.front();
            q.pop();
            cout<<now->data<<" ";
            if(now->lchild!=NULL) q.push(now->lchild);
            if(now->rchild!=NULL) q.push(now->rchild);
    }
}
int main()
{
    int n;
  while(cin>>n){
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=0;i<n;i++){
        cin>>b[i];
    }
    node *T;
    T=build(0,n-1,0,n-1);
    floor(T);
    cout<<endl;
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容