数据结构笔记六-1 (20120902)

树和二叉树:

程序说明:
1文件夹 :利用数组顺序存储二叉树;
2文件夹 :利用链表存储二叉树;
3文件夹 :利用数组顺序存储二叉树;进行遍历:
4文件夹 :利用链表存储二叉树;;进行遍历:
***********************************************************
树:
非线性结构:
空树:n=0;
非空树:
n=1:
n>1:互不相交的有限集合。
子树.
有且只有一个根结点,只有后继,没有前驱。
如果结点大于1,根有后继;

结点:
结点的度:拥有子树的数目。即直接拥有的后继。
结点的后继的最大值为树的度。
叶子结点:
父结点和子结点;
兄弟结点等;
结点之间的路径。

森林是有M课不相关的树组成的。
*******************************
二叉树:
或者是一个空树,或者是有一个根结点加上一个称为左子树和一个称为右子树的组成的一个树。如果有孩子,最多有两个孩子。
结点的层次和树的深度;
性质:
1.在二叉树的第i层上,最多有2^(i-1)的结点;(如果根结点是第1层),
2.有i层的二叉树,总共右如果结点从第一层开始,总共最大有2^i -1 ;
3.有n0(叶子结点),n1(度为1的结点),n2(度为2的结点)三个度的结点,则n0=n2+1;
推导:n0+n1+n2=n;n1+2n2=b;n-1=b;-->n0+n1+n2-1=n1+2n2;-->n0=n2+1;
4.满二叉树(个数为2^k -1),完全二叉树。
具有n个结点的完全二叉树的深度为[log2(n)]+1。
5.对有n个结点的完全二叉树进行从上到下,从左到右的编号,若i!=0,则i结点的父结点为i/2;i结点如果有孩子,则左孩子为2*i,右孩子为2*i+1;

*****************************
二叉树的存储,利用顺序存储和链表的存储;
顺序存储:左子树小,右子树大,进行排序和查找;利用下标来实现。
第一个数是根,第二个数和根比较,小就放在左子树,大就放在右子树。
该存储方法浪费了空间。适合满二叉树的形式。
遍历:
例如6 3 2 5 9 7 8 1 4
层次遍历:
先根遍历,前序遍历,前缀遍历。根-左-右:632154978;
中根遍历,中序遍历,中缀遍历;左-根-右:123456789;
后根遍历,后序遍历,后缀遍历:左-右-根:124538796;


链表存储:利用指针rchild,lchild和father来进行操作。

 

程序:

1文件夹:

******************************arrbtree.c*******************************

/*
 *wuxiuwen
 *20120902
 *利用数组及下标实现二叉树
 *
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define N 5

typedef struct node
{
	int data;
	int flag;//flag=1,说明右数据
}NODE;



int main()
{
//	NODE a[N];
	NODE *a =NULL;
	int num =N;
	int d;
	int i;
	int end =0;
	a = (NODE*)malloc(sizeof(NODE)*(num+1));  //设置一段空间进行操作
	memset(a,0,sizeof(NODE)*num+1);
	while(scanf("%d",&d)==1)     //如果输入的不是数字,就会跳出循环
	{
		i=1;                  //0不算,从第一个开始计算
	    	while(a[i].flag ==1)  //如果该位置有数字,则进一步比较,
		    			//找到放置数据的地方,
	    	{			//规则为:第一个数是根,第二个数和根比较//,小就放在左子树,大就放在右子树。
			if(a[i].data > d)
				i = i*2;   //放在左孩子处
			else 
			    	i=i*2+1;  //放置在右孩子处
		}
    		if(end <i)                             
		{	
		    	end = i;        //确定二叉树的长度
			if(end > num)
			{
			    	a = (NODE*)realloc(a,sizeof(NODE)*(end+1));
				memset(a+num+1,0,(end-num)*sizeof(NODE));
				num = end;
			}
		}

		a[i].data=d;
		a[i].flag=1;		
	}
	for(i=1;i<=end;i++)
	{
		printf("%d ",a[i].data);
	}
	printf("\n");
	return 0;
}

*****************执行结果*********************

[root@localhost 1]# gcc arrbtree.c
[root@localhost 1]# ./a.out

6 3 2 5 9 7 8 1 4 f
6 3 9 2 5 7 0 1 0 4 0 0 8
[root@localhost 1]#

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

2文件夹:

*************利用链表形成二叉树***************************


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

#define N 5

typedef struct node
{
	int data;
	struct node* lchild;
	struct node* rchild;
	struct node* father;
}NODE;

NODE *getnode(int d)
{
	
	NODE *pnew=(NODE *)malloc(sizeof(NODE)*N);
	if(pnew == NULL)
	{
		printf("内存分配失败\n");
		return ;
	}
	pnew->father = pnew->lchild = pnew->rchild=NULL;
	pnew->data=d;
}
int main()
{
	NODE *root=NULL;
	NODE *pnew=NULL;
	NODE *p=NULL;
	int d;
	while(scanf("%d ",&d)==1)
	{
		pnew=getnode(d);
		if(root==NULL)
		{
			root = pnew;
			continue;
		}
		p=root;
		while(p !=NULL)
		{
			if(p->data < d)
			{
				if(p->rchild != NULL)
					p = p->rchild;
				else
				{
				    	p->rchild = pnew;
					pnew ->father = p;
					break;
				}
			}
			else
			{
				if(p->lchild !=NULL)
				    	p = p->lchild;
				else
				{
				    	p->lchild = pnew;
					pnew->father =p;
					break;
				}
			}
		}
	}

}


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值