1. 程式人生 > 其它 >浪漫側影(c/c++完整程式碼)

浪漫側影(c/c++完整程式碼)

由於做到了這題(7-9 浪漫側影(仿2021 520鑽石爭霸賽7-8—浙江大學 陳越),在網上又沒找到什麼程式碼,那我就補充一下,因為找到的那個C++的程式碼在PTA上也沒全部通過
做這道題要對層序遍歷比較瞭解才能看懂我在主函式的那塊核心程式碼,所以不太明白的話就去看層序遍歷吧,哦,那塊我會講一下的
題目要求:
“側影”就是從左側或者右側去觀察物體所看到的內容。例如上圖中男生的側影是從他右側看過去的樣子,叫“右檢視”;女生的側影是從她左側看過去的樣子,叫“左檢視”。 520 這個日子還在打比賽的你,也就抱著一棵二叉樹左看看右看看了…… 我們將二叉樹的“側影”定義為從一側能看到的所有結點從上到下形成的序列。例如下圖這棵二叉樹,其右檢視就是 { 1, 2, 3, 4, 5 },左檢視就是 { 1, 6, 7, 8, 5 }。

於是讓我們首先通過一棵二叉樹的中序遍歷序列和後序遍歷序列構建出一棵樹,然後你要輸出這棵樹的左檢視和右檢視。

輸入格式:

輸入第一行給出一個正整數 N (≤20),為樹中的結點個數。隨後在兩行中先後給出樹的中序遍歷和後序遍歷序列。樹中所有鍵值都不相同,其數值大小無關緊要,都不超過 int 的範圍。

輸出格式:

第一行輸出右檢視,第二行輸出左檢視,格式如樣例所示。

輸入樣例:

在這裡給出一組輸入。例如:

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

輸出樣例:

在這裡給出相應的輸出。例如:
首先看一下c++

R: 1 2 3 4 5
L: 1 6 7 8 5


#include<bits/stdc++.h>		    //建立一棵二叉樹                           
using namespace std;
 
int N,in[2000],back[2000];            //N 中序 後序
int flag=1;                           //判斷有問題                                      
int height=-1;	                      //深度
 
 
typedef struct BitNode{		        //二叉連結串列結點結構 
	int data;		        //結點資料 
	struct BitNode *lchild,*rchild;		    //左右孩子指標 
}BitNode,* BitTree;		        //並列改名,定義結點用BitNode,定義結點指標用BitTree 
 
 
BitTree CreateTree(int inl,int inr,int backl,int backr)	    //建立二叉樹函式 
{
	if(inl==inr)	                //只有一個元素 
	{
		if(back[backl]!=in[inl])
		{
			flag=0;            //判斷錯誤
			return NULL;
		}
	}
       
 
	if(backl>backr)	return NULL;        
	BitTree a = new BitNode;        //分配空間(C++用的是new)
	a->data = back[backr];
	
	int m;
	for(int i=inl;i<=inr;i++)	//找根的位置下標 
	{
		if(in[i]==back[backr])
		{
			m = i;
			break;
		}
	}							
								//m是中序中的位置,用於後序要慎重! 
	a->lchild = CreateTree(inl,m-1,backl,backl+m-inl-1);	//最後位置不能寫back+m-1,應該相對backl控制數量 
	a->rchild = CreateTree(m+1,inr,backl+m-inl,backr-1);    //這裡寫不好就會一直遞迴,段錯誤 
	return a;
}
void get_height(BitTree a,int ceng)        //求深度函式
{
	if(a==NULL)	
	{
		if(ceng>height)	height = ceng;                                
		return;
	}
	get_height(a->lchild,ceng+1);
	get_height(a->rchild,ceng+1);
	ceng++;
}
 
queue<BitTree>q;		//結構指標佇列 
vector<int>vec;			//開個不定長陣列                               

int main()
{
	cin>>N;
	for(int i=0;i<=N-1;i++)
		cin>>in[i];
	for(int i=0;i<=N-1;i++)
		cin>>back[i];
	
	BitTree root = CreateTree(0,N-1,0,N-1);	                        
	get_height(root,0);
	
        BitTree a[height][10000];      //定義一個結構指標型別的陣列,用於儲存每一層樹的節點,就是個節點的集合體,和根結點的定義沒什麼區別
        a[0][0]=root;             //第一層第一個就是根節點
        
	for(int i=1;i<height;i++)    //核心程式碼,運用層序遍歷思想
	{
                int k=0;
		for(int j=0;a[i-1][j]!=NULL;j++){    //從第二層開始遍歷,若上層第一個不為空就遍歷到同層的第二個,目的是為了把這層的結點都賦到對應層數數組裡
                    if(a[i-1][j]->lchild!=NULL){a[i][k]=a[i-1][j]->lchild;k++;}     //j只是遍歷用
                    if(a[i-1][j]->rchild!=NULL){a[i][k]=a[i-1][j]->rchild;k++;}
                }
	}
        cout<<"R: ";
        for(int i=0;i<height;i++){
            int j=0;
            for(j=0;a[i][j]!=NULL;j++);
            if(i!=0) cout<<" ";      //如果PTA格式錯誤大概就是空格問題,很好解決的
            cout<<a[i][j-1]->data;
        }
        cout<<endl<<"L: ";
        for(int i=0;i<height;i++){
            if(i!=0) cout<<" ";
            cout<<a[i][0]->data;
        }
	return 0;
}

然後看看c的程式碼(和上面其實沒區別的)

#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int ElemType;
#define MaxSize 100
char post[100]; 
char in[100];
int n,height=-1;	  
typedef struct BTNode* BiTree;
struct BTNode
{
	ElemType data;
	BiTree lchild;
	BiTree rchild;
};
//順序迴圈佇列定義
typedef struct {
    BiTree *base;  //存放樹型指標 為了節約空間,這裡的樹進隊,是指樹的地址進隊,而不是樹結點進隊,佇列中存放的是對各樹地址的引用)
    int front;  //頭指標,若佇列不為空,指向佇列頭元素 
    int rear;  //尾指標,若佇列不為空,指向佇列尾元素的下一個位置 
} SqQueue;
BTNode *CreateBT2(int *post,int *in,int n)
{
	BTNode *b;
	int r,*p;
	int k;
	if(n<=0) return NULL;
	r=*(post+n-1);
	b=(BTNode*)malloc(sizeof(BTNode));
	b->data=r;
	for(p=in;p<in+n;p++){
		if(*p==r)break;
	}
	k=p-in;
	b->lchild=CreateBT2(post,in,k);
	b->rchild=CreateBT2(post+k,p+1,n-k-1);
	return b;
}
void get_height(BiTree a,int ceng)        //求深度函式
{
	if(a==NULL)	
	{
		if(ceng>height)	height = ceng;
		return;
	}
	get_height(a->lchild,ceng+1);
	get_height(a->rchild,ceng+1);
	ceng++;
}
int main()
{
	BiTree t = (BiTree)malloc(sizeof(struct BTNode));
	int post[100], in[100];
//	printf("請輸入接點數:");
	scanf("%d",&n);
//	printf("請輸入中序遍歷結果:");
	for(int i=0;i<n;i++)
	scanf("%d",&in[i]);
//	printf("請輸入後序遍歷結果:");
	for(int i=0;i<n;i++)
	scanf("%d",&post[i]);
	t = CreateBT2(post,in,n);
	get_height(t,0);
    BiTree a[height][10000];
    a[0][0]=t;  
	for(int i=1;i<height;i++)
	{
        int k=0;
		for(int j=0;a[i-1][j]!=NULL;j++){
            if(a[i-1][j]->lchild!=NULL){a[i][k]=a[i-1][j]->lchild;k++;}
            if(a[i-1][j]->rchild!=NULL){a[i][k]=a[i-1][j]->rchild;k++;}
        }
	}
	printf("R:");
	for(int i=0;i<height;i++){
        int j=0;
        for(j=0;a[i][j]!=NULL;j++);
        printf(" %d",a[i][j-1]->data);
        }
        printf("\n");
        printf("L:");
        for(int i=0;i<height;i++){
            printf(" %d",a[i][0]->data);
        }
	return 0;
}

咳咳,(這是給萌新說的,大佬可以略過……。不要覺得難,其實它就是很難,廢了好大勁的,主要是我也不太會結構體什麼的,層序遍歷寫了好幾遍,構建二叉樹也弄了好幾遍,還要解決c沒有引用這個問題,嗚嗚嗚嗚………………)

最後,我本來還要弄好久,思路是知道,但怎麼把它存到陣列是真的好難想,我室友不吭不響一會就把我想好久還要想好久的問題給解決了,讓我有種想哭的衝動,不說了。

沒錯,那串核心程式碼就是他想的

吾有室友,是為神!