- 树(Tree):非线性数据结构:树,图
- 术语:
根结点(root):树中没有前驱的结点
叶子结点(leaf):没有后继的结点
双亲结点:是子女结点的前驱
子女结点:是双亲结点的后继
兄弟结点:同一个双亲结点的子女之间互称为兄弟结点
度:结点的度:一个结点的子女个数(叶子结点度为0)
树的度:树中度值最大的结点的度
树的深度:树的层次数 - 二叉树:度值最大为2的树
树状结构:
i:有且只有一个结点无前驱:根结点
ii:可有多个结点无后继:叶子结点
iii:除根和叶子外,其余结点只有一个双亲,可有多个子女 - 二叉树性质:
a》任意一棵非空二叉树的叶子结点总比双分支结点多一个
n0=n2+1
b》对二叉树按层编号:0,1,2,3…
编号为i的层最多可放2^i个结点(最大值) - 满二叉树:一棵h层的二叉树的每一层的结点个数都达到最大值
结点个数为:2^h - 1 - 完全二叉树:一棵h层的完全二叉树:
i:前h-1层是满的
ii:最后一层连续缺失右边的结点
特点:
①h-1<log2(n+1)<=h
②n为奇数无单分支结点,n为偶数有单分支结点
③满二叉树是特殊的完全二叉树 - 理想平衡二叉树(理想树):前h-1层是满的,最后一层任意摆放
满二叉树<=完全二叉树<=平衡二叉树 - 对任意一棵二叉树按层对结点进行编号:1,2,3… 注意:对缺失结点也要编号
编号为i的结点:若有左子女:编号为:2i
若有右子女:编号为:2i+1
编号为i的结点:双亲编号为:【i/2】
(i>1)
创建一棵二叉查找树,及前中后序遍历输出
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left;
struct node *right;
}BTNode;
BTNode *CreateBTree(int a[],int n)
{
BTNode *p,*parent,*root,*c;
int i;
//创建根结点
root=(BTNode *)malloc(sizeof(BTNode));
root->data=a[0];
root->left=root->right=NULL;
//创建其他结点
for(i=1;i<n;i++){
p=(BTNode *)malloc(sizeof(BTNode));
p->data=a[i];
p->left=p->right=NULL;
c=root;//每次循环都要从根开始遍历判断
while(c){
parent=c;//联动指针
if(c->data>p->data){
c=c->left;
}
else{
c=c->right;
}
}
if(parent->data>p->data){//判断要挂哪边的链
parent->left=p;
}
else{
parent->right=p;
}
}
return root;
}
void Forder(BTNode *root)
{
if(root){
printf("%4d",root->data);
Forder(root->left);//递归遍历左子树
Forder(root->right);//递归遍历右子树
}
}
void Inorder(BTNode *root)
{
if(root){
Inorder(root->left);
printf("%4d",root->data);
Inorder(root->right);
}
}
void Porder(BTNode *root)
{
if(root){
Porder(root->left);
Porder(root->right);
printf("%4d",root->data);
}
}
int main()
{
int n;
BTNode *root;
scanf("%d",&n);
int *a;
a=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
root=CreateBTree(a,n);//创建二叉查找树
Forder(root);//前序遍历
printf("\n");
Inorder(root);//中序遍历
printf("\n");
Porder(root);//后序遍历
return 0;
}
//设root指向一棵非空二叉树,在二叉树中查找关键字为key的结点,
//并返回地址,若未找到返回null,设每个结点数据域值不重复
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
BTNode *root,*c,*p,*q;
root=(BTNode *)malloc(sizeof(BTNode));
root->data=a[0];
root->left=root->right=NULL;
for(int i=1;i<n;i++){
p=(BTNode *)malloc(sizeof(BTNode));
p->data=a[i];
p->left=p->right=NULL;
c=root;
while(c){
q=c;
if(c->data>p->data){
c=c->left;
}
else{
c=c->right;
}
}
if(q->data>p->data){
q->left=p;
}
else{
q->right=p;
}
}
return root;
}
BTNode *Findkey(BTNode *r,int key)
{
BTNode *lr,*rr;
if(!r)
{
return NULL;
}
if(r->data==key){
return r;
}
else{
lr=Findkey(r->left,key);
rr=Findkey(r->right,key);
if(lr){
return lr;
}
else if(rr){
return rr;
}
else{
return NULL;
}
}
}
int main()
{
int *a;
int n,key;
printf("请输入数组长度:");
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
printf("请输入数组元素:");
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
printf("请输入key值:");
scanf("%d",&key);
BTNode *root=CreateBiTree(a,n);
root=Findkey(root,key);
if(root){
printf("%d",root->data);
}
else{
printf("NULL");
}
return 0;
}
//按行遍历二叉树的每个结点(非递归)
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
BTNode *root,*c,*p,*q;
root=(BTNode *)malloc(sizeof(BTNode));
root->data=a[0];
root->left=root->right=NULL;
for(int i=1;i<n;i++){
p=(BTNode *)malloc(sizeof(BTNode));
p->data=a[i];
p->left=p->right=NULL;
c=root;
while(c){
q=c;
if(c->data>p->data){
c=c->left;
}
else{
c=c->right;
}
}
if(q->data>p->data){
q->left=p;
}
else{
q->right=p;
}
}
return root;
}
void LevelOrder(BTNode *root)
{
BTNode **Q,*p;//声明指向存储指针的队列的指针
int front=0,rear=0;//头指针和尾指针
Q=(BTNode **)malloc(sizeof(BTNode *)*1000);//队列空间不为循环队列,要尽可能大
Q[++rear]=root;
while(front!=rear){//队列不空,执行出队,输出,入队操作
p=Q[++front];//出队
printf("%5d",p->data);//输出
if(p->left){
Q[++rear]=p->left;//左子女入队
}
if(p->right){
Q[++rear]=p->right;//右子女入队
}
}
}
int main()
{
int *a;
int n,key;
printf("请输入数组长度:");
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
printf("请输入数组元素:");
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
BTNode *root=CreateBiTree(a,n);//建立二叉排序树
LevelOrder(root);//二叉树的层次遍历
return 0;
}
//非递归前序遍历二叉树
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
BTNode *root,*c,*p,*q;
root=(BTNode *)malloc(sizeof(BTNode));
root->data=a[0];
root->left=root->right=NULL;
for(int i=1;i<n;i++){
p=(BTNode *)malloc(sizeof(BTNode));
p->data=a[i];
p->left=p->right=NULL;
c=root;
while(c){
q=c;
if(c->data>p->data){
c=c->left;
}
else{
c=c->right;
}
}
if(q->data>p->data){
q->left=p;
}
else{
q->right=p;
}
}
return root;
}
void PreOrder(BTNode *root)
{
BTNode **Q,*p;
int top=-1;//栈顶指针
Q=(BTNode **)malloc(sizeof(BTNode *)*1000);//栈空间尽可能大
Q[++top]=root;
while(top!=-1){//栈不空
p=Q[top--];//出栈
printf("%5d",p->data);
if(p->right){//右子女压栈
Q[++top]=p->right;
}
if(p->left){//左子女压栈
Q[++top]=p->left;
}
}
}
int main()
{
int *a;
int n,key;
printf("请输入数组长度:");
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
printf("请输入数组元素:");
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
BTNode *root=CreateBiTree(a,n);//建立二叉排序树
PreOrder(root);//二叉树的层次遍历
return 0;
}
//非递归中序遍历二叉树
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
BTNode *root,*c,*p,*q;
root=(BTNode *)malloc(sizeof(BTNode));
root->data=a[0];
root->left=root->right=NULL;
for(int i=1;i<n;i++){
p=(BTNode *)malloc(sizeof(BTNode));
p->data=a[i];
p->left=p->right=NULL;
c=root;
while(c){
q=c;
if(c->data>p->data){
c=c->left;
}
else{
c=c->right;
}
}
if(q->data>p->data){
q->left=p;
}
else{
q->right=p;
}
}
return root;
}
void InOrder(BTNode *root)
{
BTNode **Q,*p;
int top=-1;//栈顶指针
Q=(BTNode **)malloc(sizeof(BTNode *)*1000);//栈空间尽可能大
p=root;
while(p){//将左线入栈
Q[++top]=p;
p=p->left;
}
while(top!=-1){//栈不空
p=Q[top--];//出栈
printf("%5d",p->data);
if(p->right){//判断p的右子女是否为空,为空则不做处理
p=p->right;//p指向右子女
while(p){//入栈新的左线
Q[++top]=p;
p=p->left;
}
}
}
}
int main()
{
int *a;
int n,key;
printf("请输入数组长度:");
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
printf("请输入数组元素:");
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
BTNode *root=CreateBiTree(a,n);//建立二叉排序树
InOrder(root);//二叉树的层次遍历
return 0;
}
//非递归后序遍历
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left,*right;
}ElemSN;
ElemSN *CreateBiTree(int a[],int n)
{
ElemSN *root,*c,*p,*q;
root=(ElemSN *)malloc(sizeof(ElemSN));
root->data=a[0];
root->left=root->right=NULL;
for(int i=1;i<n;i++){
p=(ElemSN *)malloc(sizeof(ElemSN));
p->data=a[i];
p->left=p->right=NULL;
c=root;
while(c){
q=c;
if(c->data>p->data){
c=c->left;
}
else{
c=c->right;
}
}
if(q->data>p->data){
q->left=p;
}
else{
q->right=p;
}
}
return root;
}
/*void ProBiTree(ElemSN *root)
{
ElemSN **stack,*p=NULL;
stack=(ElemSN **)malloc(sizeof(ElemSN *)*1000);//分配栈空间
int top=-1;//栈顶指针
while(root||top!=-1){//根结点不空且栈不空
while(root){//将左子树压栈
stack[++top]=root;
root=root->left;
}
if(top!=-1){//栈不空
root=stack[top];//出栈
if(root->right==NULL||root->right==p){//无右孩子或者有孩子已经访问过
printf("%4d",root->data);
top--;
p=root;
root=NULL;//避免重复入栈
}
else{//有右孩子,但未被访问过
root=root->right;
}
}
}
}*/
void ProBiTree(ElemSN *root)
{
ElemSN **stack,*p=NULL;
stack=(ElemSN **)malloc(sizeof(ElemSN *)*1000);//分配栈空间
int top=-1;//栈顶指针
while(root||top!=-1){//根结点不空且栈不空
if(root){//将左子树压栈
stack[++top]=root;
root=root->left;
}
else{//栈不空
root=stack[top];//出栈
if(root->right==NULL||root->right==p){//无右孩子或者有孩子已经访问过
printf("%4d",root->data);
top--;
p=root;
root=NULL;//避免重复入栈
}
else{//有右孩子,但未被访问过
root=root->right;
}
}
}
}
int main()
{
int n;
int *a;
printf("请输入数组长度:");
scanf("%d",&n);
a=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
ElemSN *root=CreateBiTree(a,n);
ProBiTree(root);
return 0;
}