1. 程式人生 > >☆ 二叉樹的前序儲存、行式儲存與前序遍歷

☆ 二叉樹的前序儲存、行式儲存與前序遍歷

二叉樹的儲存與遍歷的方式有很多種,本文主要介紹二叉樹的鏈式儲存;

其中儲存與遍歷均採用前序序列。

****************************************************************************************************************************************

★下面給出了兩種表示型別(實際上是一樣的,均採用了二級指標來儲存節點資訊):

   型別一:結構體重新命名的時候沒有使用指標形式

#include <stdio.h>
#include <stdlib.h>
typedef int Status;
typedef char TElemType;

typedef struct BiNode
{
	TElemType data;
	struct BiNode *lchild, *rchild;
}BiNode;


void CreatBiTree(BiNode **T)    //二級指標傳入節點地址的地址,不使用return帶出可以更好地儲存各個鏈之間的關係
{
	TElemType ch;
	scanf_s("%c", &ch);
	getchar();    //注意這裡要使用getchar()來吸收回車
	if (ch == '#')
	{
		*T = NULL;
	}
	else
	{
		if (!((*T) = (BiNode *)malloc(sizeof(BiNode))))
		{
			printf("Memory allocate error!");
			exit(0);
		}
		(*T)->data = ch;
		CreatBiTree(&(*T)->lchild);
		CreatBiTree(&(*T)->rchild);
	}
}

void BiTreeTraverse(BiNode *T)
{
	if (T == NULL)
	{
		return;
	}
	printf(">>> %c\n", T->data);
	BiTreeTraverse(T->lchild);
	BiTreeTraverse(T->rchild);
}

int main()
{
	BiNode *T;  
	system("title 二叉樹的儲存與遍歷");
	printf("請按照前序連續輸入二叉樹中節點的值(一個字元)\n");
	CreatBiTree(&T);    //傳進指標的地址,方便直接從函式中帶出
	system("pause");
	BiTreeTraverse(T);
	printf("-END-\n");
    return 0;
}

   型別二:結構體重新命名的時候使用指標形式

#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0

typedef int Status;
typedef char TElemType;

typedef struct BiTNode			//二叉樹的二叉連結串列節點結構 
{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

void CreatBiTree(BiTree *T)  		//使用二級指標建立二叉連結串列()二叉樹 
{
	TElemType ch;
	scanf_s("%c",&ch);
    getchar();    //注意這裡要使用getchar()來吸收回車
	if(ch=='#')
	{
		*T=NULL;
	} 
	else
	{
		if(!(*T=(BiTree)malloc(sizeof(BiTNode))))			//動態分配空間 
		{
			printf("Memory allocate error!");
			exit(ERROR); 
		}
		(*T)->data=ch;			//生成根節點 
		CreatBiTree(&(*T)->lchild);			//構造左子樹 
		CreatBiTree(&(*T)->rchild);			//構造右子樹 
	}
}

void PreOrderTraverse(BiTree T)
{
	if(T==NULL)
	{
		
		return;
	}
	printf("%c",T->data);
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
}

Status main()
{
	BiTree T;
	system("title 二叉連結串列的建立與遍歷"); 
	printf("請按照前序連續輸入二叉樹中節點的值(一個字元)\n"); 
	CreatBiTree(&T);
	system("pause");
	PreOrderTraverse(T);
}

這裡在建立二叉樹的時候,使用的是二級指標,

使用二級指標的好處在於不用使用return就可以直接帶出自己想要的值,地址的修改會直接導致值的修改;這裡就是指標的地址被修改就會直接改變指標的值。於是就可以直接使用改變後的指標。

但是在這裡建立的時候使用二級指標比使用以及指標方便了些,具體有關二級指標的介紹以及使用可以參考另一位博主的部落格:Q點我直達Q

2018.11.11晚更新:

這裡附上一個完整的demo程式(實現前序儲存、行式儲存與前序遍歷);

1> 執行結果 (這裡的輸入表示的是兩個不同的二叉樹):

2> 原始碼: < 原始碼部分使用了C++的語句 >

  這裡涉及了C++萬能標頭檔案 stdc++.h,但是在VS中並不存在該標頭檔案,可以額外下載新增;

  ( 對於萬能標頭檔案,在軟體DevC++中可以直接使用,而且使用的格式是#include<bits/stdc++.h>,

   這裡的標頭檔案名稱為stdc++.h ,寫成bits/stdc++.h 是因為該檔案被放在了相應標頭檔案存放路徑的bits資料夾中;

   我們在網上下載的標頭檔案會直接是stdc++.h,如果想直接使用,可以把標頭檔案直接放在VS相應安裝目錄下,

   如下圖;如果想使用 #include<bits/stdc++.h> 的格式,在該目錄下建立一個bits資料夾,將該標頭檔案放進去即可。

   檔案安裝目錄基於VS2015講解,不同的VS版本安裝目錄可能略有不同,可適當調整解決。)

 

#include <bits/stdc++.h>
#define R_N 7
using namespace std;
typedef int Status;
typedef char TElemType;

typedef struct BiNode
{
	TElemType data;
	struct BiNode *lchild, *rchild;
}BiNode;


void CreatBiTree(BiNode **T)    //二級指標傳入節點地址的地址,不使用return帶出可以更好地儲存各個鏈之間的關係
{
	TElemType ch;
	scanf("%c", &ch);
	//getchar();     //使用空格進行間隔輸入
	if (ch == '#')
	{
		*T = NULL;
	}
	else
	{
		if (!((*T) = (BiNode *)malloc(sizeof(BiNode))))
		{
			printf("Memory allocate error!");
			exit(0);
		}
		(*T)->data = ch;
		CreatBiTree(&(*T)->lchild);
		CreatBiTree(&(*T)->rchild);
	}
}

BiNode * CreatBiNode_R(char i)
{
	BiNode *p;
	p = new BiNode;
	if (i == '#')
	{
		p = NULL;
	}
	else
	{
		p->data = i;
		p->lchild;
		p->rchild;
	}
	return p;
}

BiNode * CreatBiTree_R()
{
	BiNode *p[R_N] = { NULL };
	cout << "Please enter the values :\n";
	for (int i = 0; i < R_N; i++)
	{
		char value;
		cin >> value;
		//getchar()
		p[i] = CreatBiNode_R(value);
	}
	for (int i = 0; i < R_N / 2; i++)
	{
		if (p[i] == NULL)
		{
			continue;
		}
		else
		{
			p[i]->lchild = p[i * 2 + 1];
			p[i]->rchild = p[i * 2 + 2];
		}
	}
	return p[0];
}

void BiTreeTraverse(BiNode *T)
{
	if (T == NULL)
	{
		return;
	}
	printf(">>> %c\n", T->data);
	BiTreeTraverse(T->lchild);
	BiTreeTraverse(T->rchild);
}

int main()
{
	BiNode *T;  
	system("title 二叉樹的儲存與遍歷");
	printf("請按照前序連續輸入二叉樹中節點的值: \n");
	CreatBiTree(&T);    //傳進指標的地址,方便直接從函式中帶出
	system("pause");
	BiTreeTraverse(T);
	printf("-END-\n");
	system("pause");
	printf("請按照行式連續輸入二叉樹中節點的值: \n");
	BiNode *P = CreatBiTree_R();
	BiTreeTraverse(P);
	cout << "Traverse This BinaryTree Complete! " << endl;
    return 0;
}

****************************************************************************************************************************************

             最快的腳步不是跨越,而是繼續,最慢的步伐不是小步,而是徘徊。

****************************************************************************************************************************************