数据结构基础之二叉链表的创建

一、键盘交互创建二叉树

//键盘交互递归创建二叉树子树函数
void createSubTree(btNode *&p, int k)
{
	//k=1--左子树;k=2--右子树
	btNode *s;
	elementType x;
	cout<<"请输入结点元素数值,'/'表示无子树,x=";
	cin>>x;
	if(x!='/')
	{
		s=new btNode;
		s->data=x;
		s->lChild=NULL;
		s->rChild=NULL;
		if(k==1)
			p->lChild=s;     //s接到p的左孩子
		if(k==2)
			p->rChild=s;     //s接为p的右孩子
		createSubTree(s,1);  //递归创建s的左子树
		createSubTree(s,2);  //递归创建s的右子树	
	}
}

//键盘交互创建二叉树主控函数
void createBTConsole(btNode *&T)
{
	btNode *p;
	elementType x;
	cout<<"请按先序序列输入二叉树结点,(‘/’表示无子树):"<<endl;
	cout<<"请输入结点元素数值,'/'表示无子树,x=";
	cin>>x;
	if(x=='/')
		return;    //空树,退出
	T=new btNode;
	T->data=x;
	T->lChild=NULL;
	T->rChild=NULL;

	createSubTree(T,1);    //创建根结点的左子树
	createSubTree(T,2);    //创建根结点的右子树
}

二、根据二叉树的顺序表存储创建二叉链表

//完全二叉树顺序存储方式创建二叉链表结构二叉树
//创建顺序表
void getCompleteArr(elementType *arr, int &num)
{
	    //缺少的结点数值用'/'代替
	    //用'#'结束结点输入
	    //arr为结点数组
	    //num返回实际结点数
	elementType x;
	int i=1;   //arr[0]单元不用
	num=0;
	cout<<"请按完全二叉树方式输入二叉树结点,‘/’表示缺少结点,'#'结束输入。"<<endl;
	cout<<"请输入结点元素数值,'/'表示缺少结点,'#'结束输入,x=";
	cin>>x;
	while(x!='#')
	{
		*(arr+i)=x;
		i++;
		num++;

		cin>>x;
	}
}
//创建二叉链表
void createBtArr(btNode* &T, elementType* InArr, int i, int n)
{
	//T--为根结点指针
	//InArr--为按完全二叉树存储的树的结点数组
	//i--当前结点序号
	//n--二叉树结点总数
	if(i>n)
		return;
	if(InArr[i]!='/')       //有效数据创建结点
	{
		T=new btNode;       //创建根结点
		T->data=InArr[i];   //结点赋值
		T->lChild=NULL;
		T->rChild=NULL;
	}
	createBtArr(T->lChild, InArr, 2*i, n);    //递归创建T的左子树
	createBtArr(T->rChild, InArr, 2*i+1, n);  //递归创建T的右子树
}

三、读取数据文件创建二叉树

//删除字符串、字符数组左边空格
void strLTrim(char* str)
{
	int i,j;
	int n=0;
	n=strlen(str)+1;
	for(i=0;i<n;i++)
	{
		if(str[i]!=' ')  //找到左起第一个非空格位置
			break;
	}
	    //以第一个非空格字符为手字符移动字符串
	for(j=0;j<n;j++)
	{
		str[j]=str[i];
		i++;
	}
}

//从文本文件数据读入到数组中,同时返回实际结点数量
bool ReadFileToArray(char fileName[], char strLine[NODENUM][3], int & nArrLen)
{
	//读文本文件数据到数组,返回数组及其长度
	FILE* pFile;      //定义二叉树的文件指针
	char str[1000];   //存放读出一行文本的字符串
	char strTemp[10]; //判断是否注释行

	pFile=fopen(fileName,"r");
	if(!pFile)
	{
		cout<<"错误:文件"<<fileName<<"打开失败。"<<endl;
		return false;
	}

	while(fgets(str,1000,pFile)!=NULL)  //跳过空行和注释行
	{
		   //删除字符串左边空格
		strLTrim(str);
		if (str[0]=='\n')               //空行,继续读取下一行
			continue;

		strncpy(strTemp,str,2);
		if(strstr(strTemp,"//")!=NULL)  //跳过注释行
			continue;
		else                            //非注释行、非空行,跳出循环
			break;
	}
           //循环结束,str中应该已经是二叉树数据标识"BinaryTree",判断文件格式
	if(strstr(str,"BinaryTree")==NULL)
	{
		printf("错误:打开的文件格式错误!\n");
		fclose(pFile);           //关闭文件
		return false;
	}


    

	//nArrLen=0;
	//while(fscanf(pFile,"%c  %c  %c\n",&strLine[nArrLen][0],&strLine[nArrLen][1],&strLine[nArrLen][2])!=EOF)	
	//{
		//printf("%c\n",strLine[nArrLen][0]);
	//	nArrLen++;
	//}

	nArrLen=0;     //数组行号初始化为0
	while(fgets(str,1000,pFile)!=NULL)
	{
		    //删除字符串左边空格
		strLTrim(str);
		if (str[0]=='\n')  //空行,继续读取下一行
			continue;
		
		strncpy(strTemp,str,2);
		if(strstr(strTemp,"//")!=NULL)  //注释行,跳过,继续读取下一行
			continue;

		char* token=strtok(str," ");   //以空格为分隔符,分割一行数据
		if(token==NULL)  //分割为空串,失败退出
		{
			printf("错误:读取二叉树结点数据失败!\n");
			fclose(pFile); //关闭文件
			return false;
		}
		
		strLine[nArrLen][0]=*token;  //获取结点数据
		token = strtok( NULL, " ");  //读取下一个子串,即此结点的左子树信息
		if(token==NULL)  //分割为空串,失败退出
		{
			printf("错误:读取二叉树结点数据失败!\n");
			fclose(pFile); //关闭文件
			return false;
		}
		strLine[nArrLen][1]=*token;  //获取此结点的左子树信息数据
		token = strtok( NULL, " ");  //读取下一个子串,即此结点的右子树信息
		if(token==NULL)  //分割为空串,失败退出
		{
			printf("错误:读取二叉树结点数据失败!\n");
			fclose(pFile); //关闭文件
			return false;
		}
		strLine[nArrLen][2]=*token;  //获取此结点的右子树信息数据

		nArrLen++;  //数组行号加1	
	}

	fclose(pFile); //关闭文件
	return true;
}


//从数组创建二叉树--数组中保存的是二叉树的先序序列,及每个结点的子树信息
bool CreateBiTreeFromFile(btNode* & pBT, char strLine[NODENUM][3],int nLen, int & nRow)
{
	//strLine[NODENUM][3]--保存节点数据的二维数组
	//nLen--数组长度,即:节点个数
	//nRow--数组当前行号

	if((nRow>=nLen) || (nLen==0))
		return false;  //数据已经处理完毕,或者没有数据,退出

	//根据数组数据递归创建子树
	pBT=new btNode;
	pBT->data=strLine[nRow][0];
	pBT->lChild=NULL;
	pBT->rChild=NULL;
	
	int nRowNext=nRow;  //保留本次递归的行号	

	if(strLine[nRowNext][1]=='1')  //当前结点有左子树,递归创建左子树,读下一行数据
	{
		nRow++;
		CreateBiTreeFromFile(pBT->lChild, strLine,nLen,nRow);
	}

	if(strLine[nRowNext][2]=='1')  //当前结点有右子树,递归创建右子树,读下一行数组
	{
		nRow++;
		CreateBiTreeFromFile(pBT->rChild, strLine,nLen,nRow);		
	}

	return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值