最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

中序線索二叉樹

2023-01-11 06:47 作者:就叫大嘴吧  | 我要投稿


#include<iostream>
#include<stdio.h>
#include <stdlib.h>

using namespace std;

/*
		1、為什么要線索化二叉樹?
		對(duì)于經(jīng)常需要遍歷或查找結(jié)點(diǎn) 在遍歷所得線性序列中的 前驅(qū)和后繼信息,
		線索化二叉樹查找效率高,不需要設(shè)棧。
		
		2、如何查找前驅(qū)和后繼信息? 
		當(dāng)二叉樹以二叉鏈表作為存儲(chǔ)結(jié)構(gòu)時(shí),只能找到結(jié)點(diǎn)的左、右孩子信息,
		而不能直接得到結(jié)點(diǎn)在一序列中的前驅(qū)和后繼信息,前序和后繼信息只有在遍歷的動(dòng)態(tài)過(guò)程中才能得到。 
*/ 



typedef struct treenode{
	char data;
	struct treenode *lchild, *rchild;
	// ltag = 0:lchild指針指向結(jié)點(diǎn)的左孩子 ?ltag = 1:lchild指針指向結(jié)點(diǎn)的前驅(qū) 
	// rtag = 0:rchild指針指向結(jié)點(diǎn)的右孩子 ?rtag = 1:rchild指針指向結(jié)點(diǎn)的后繼 
	int ltag, rtag;
}treenode, *tree; 

void buildtree(tree &t);
void InOrderThreading(tree &thrt, tree t);
void InThreading(tree p);
void InOrderTraverse(tree thrt); 
void InOrderTraverseReverse(tree thrt);

// 先序序列建立二叉樹 
void buildtree(tree &t){
	char ch;
	ch = getchar();
	
	if(ch == '#'){
		t = NULL;
	}
	else{
		t = (treenode *)malloc(sizeof(treenode));
		t->data = ch;
		t->lchild = NULL;
		t->rchild = NULL;
		t->ltag = 0;
		t->rtag = 0;
		
		buildtree(t->lchild);
		buildtree(t->rchild);
	}
}

// 前驅(qū)結(jié)點(diǎn)指針 (全局變量) 
treenode* pre; 

// 中序線索化 
void InOrderThreading(tree &thrt, tree t){
	// 建頭結(jié)點(diǎn) (為頭節(jié)點(diǎn)指針分配存儲(chǔ)空間)
	thrt = (treenode*) malloc(sizeof(treenode));
	thrt->ltag = 0;
	thrt->rtag = 1;
	// 右指針 回指 
	thrt->rchild = thrt;
	if(t == NULL){
		// 二叉樹t 為空,頭節(jié)點(diǎn)的左指針 回指 
		thrt->lchild = thrt;
	} 
	else{
		thrt->lchild = t;
		pre = thrt;
		// 中序遍歷 進(jìn)行 中序線索化 
		InThreading(t);
		// 最后一個(gè)結(jié)點(diǎn) 線索化
		pre->rchild = thrt;
		pre->rtag = 1;
		thrt->rchild = pre; 
	}
}

// 中序遍歷 進(jìn)行中序線索化
void InThreading(tree p){
	// 結(jié)點(diǎn) 非空 
	if(p){
		// 向左延申 找中序遍歷的第一個(gè)結(jié)點(diǎn) 
		InThreading(p->lchild); // 左子樹線索化 
		
		if(p->lchild == NULL){ // 當(dāng)前結(jié)點(diǎn) 左孩子 為空 
			p->ltag = 1;
			// 將 左孩子指針 指向 中序遍歷時(shí)的 前驅(qū)結(jié)點(diǎn) 
			p->lchild = pre;
		} 
		
		if(pre->rchild == NULL){ // 前驅(qū)結(jié)點(diǎn) 右孩子 為空 
			pre->rtag = 1;
			// 將 前驅(qū)結(jié)點(diǎn)的右孩子指針 指向 當(dāng)前結(jié)點(diǎn) 
			pre->rchild = p; ?
		}
		// 更新前驅(qū)結(jié)點(diǎn) 
		pre = p;
		
		InThreading(p->rchild); // 右子樹線索化 
	}
} 


// p->rtag = 1:右指針是線索,其后繼為 右孩子 
// p->rtag = 0:該結(jié)點(diǎn)有右孩子,則其后繼為 右子樹最左下結(jié)點(diǎn)
// 中序線索二叉樹的遍歷
void InOrderTraverse(tree thrt){
	// p 指向原二叉樹的根結(jié)點(diǎn) 
	treenode* p = thrt->lchild;
	while(p != thrt){
		// 第一次 while 循環(huán):找到 中序遍歷的第一個(gè)結(jié)點(diǎn) 
		// 后面每一次 while 循環(huán):找到 右子樹最左下結(jié)點(diǎn) 
		while(p->ltag == 0){
			p = p->lchild;
		}
		// 訪問第一個(gè)結(jié)點(diǎn) 
		printf("%c	", p->data);
		// 右標(biāo)志為 1,可直接得到 后繼結(jié)點(diǎn) 
		while(p->rtag == 1 && p->rchild != thrt){
			p = p->rchild;
			printf("%c	", p->data);
		}
		// while循環(huán)結(jié)束,p->rtag = 0;
		// 右標(biāo)志為 0,則 后繼為 右子樹最左下角結(jié)點(diǎn) 
		// 右標(biāo)志為 0,將 p指針 指向 p的右孩子 ?
		p = p->rchild;
	} 
} 

// p->ltag = 1:左指針是線索,其前序?yàn)?左孩子 
// p->ltag = 0:該結(jié)點(diǎn)有左孩子,則其前驅(qū)為 左子樹最右下結(jié)點(diǎn)
// 逆序遍歷中序線索二叉樹 
void InOrderTraverseReverse(tree thrt){
	treenode* p = thrt->lchild;
	while(p != thrt){
		// 第一次 while 循環(huán):查找中序遍歷的最后一個(gè)結(jié)點(diǎn) 
		// 后面每一次 while 循環(huán):找到左子樹最右下結(jié)點(diǎn) 
		while(p->rtag == 0){
			p = p->rchild;
		}
		// 訪問最后一個(gè)結(jié)點(diǎn) 
		printf("%c	", p->data);
		while(p->ltag == 1 && p->lchild != thrt){
			p = p->lchild;
			printf("%c	", p->data);
		}
		p = p->lchild;
	}
	printf("\n");
}

int main(){
	
	tree t;
	tree thrt;
	// 先序序列:FECA#B##D###HG##I##
	buildtree(t);
	// 中序線索化 
	InOrderThreading(thrt, t);
	
	// 中序線索二叉樹的遍歷:A B C D E F G H I ?
	InOrderTraverse(thrt); 
	printf("\n"); 
	// 逆序遍歷中序線索二叉樹:I H G F E D C B A 
	InOrderTraverseReverse(thrt);
	/*
				F
			E		H
		 C ? ? ? ?G ? ?I
	 ?A ? ?D
	 ? ?B
	*/
	return 0;
}


中序線索二叉樹的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
出国| 延吉市| 盘锦市| 林西县| 鄂托克旗| 中山市| 枞阳县| 金寨县| 淮南市| 义乌市| 张家港市| 斗六市| 双城市| 金坛市| 海门市| 定日县| 汝阳县| 济源市| 蚌埠市| 达日县| 桦甸市| 通州市| 恩施市| 察隅县| 石棉县| 绥滨县| 民乐县| 岑巩县| 利辛县| 亳州市| 特克斯县| 新田县| 焦作市| 松江区| 深圳市| 体育| 迁西县| 双柏县| 长兴县| 新巴尔虎左旗| 吴堡县|