树结构
结点的度(Degree):结点拥有的子树数目
树的度:树中各结点度的最大值
叶子结点(Leaf):度为0的结点
孩子结点(Child):一个结点的子树的根结点
双亲结点(Parent):与孩子结点对应
兄弟结点(Sibling):一个双亲结点的孩子结点之间为兄弟结点
结点的层次(Level):从根结点开始,根结点为第一层,根结点的孩子结点为第二层,以此类推。
树的深度(Depth):树中结点的最大深度
树的性质:
二叉树
满二叉树:一颗二叉树的任意一个结点或者是叶子结点,或者有两颗子树,同时叶子结点都集中在二叉树的最下面一层
完全二叉树:二叉树中最多只有最下面两层结点的度小于2,且最下面一层的结点都依次排列在该层最左边的位置上
例如:
二叉树的性质:
二叉树的创建与遍历
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
int data;
treenode * left;
treenode * right;
};
typedef treenode Node;
Node *create(int a[],int length)
{
int i;
Node *p[length] = {0}; //指针数组
for(i = 0; i < length; i ++) //写入数据
{
p[i] = (Node *)malloc(sizeof(Node));
if(p[i] == NULL)
{
return NULL;
}
p[i]->data = a[i];
p[i]->left = NULL;
p[i]->right = NULL;
}
for(i = 0;i < length/2 ; i ++) //连接结点
{
p[i]->left = p[2 * i + 1];
p[i]->right = p[2 *i + 2];
}
return p[0];
}
void prenode(Node *root) //前序 (根——左——右)
{
if(root == NULL)
{
return;
}
printf("%d ",root->data);
prenode(root->left);
prenode(root->right);
}
void Midnode(Node *root) //中序 (左——根——右)
{
if(root == NULL)
{
return;
}
midnode(root->left);
printf("%d ",root->data);
midnode(root->right);
}
void posnode(Node * root)//后序 (左——右——根)
{
if(root == NULL)
{
return;
}
postnode(root->left);
postnode(root->right);
printf("%d ",root->data);
}
int main()
{
int a[] = {0,1,2,3,4,5,6,7,8,9};
int length = sizeof(a)/sizeof(int);
Node *root = create(a,length);
prenode(root);
printf("\n");
midnode(root);
printf("\n");
posnode(root);
printf("\n");
return 0;
}
二叉树的遍历:
先序列创建一颗二叉树
void CreateBiTree(BiTree *T)
{
char c;
scanf("%c",&c);
if(c ==' ')
{
*T = NULL;
}
else
{
*T = (BiTNode *)malloc(sizeof(BiTNode)); //创建根结点
(*T)->data = c; //放入数据
CreateBiTree(&((*T)->lchild)); //递归的创建左子树
CreateBiTree(&((*T)->lchild)); //递归的创建右子树
}
}
先序遍历(根结点→左子树→右子树)
void PreOrderTraverse(BiTree T)
{
if(T)
{
printf("%d\n",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
中序遍历(左子树→根结点→右子树)
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
printf("%d",T->data);
InOrderTraverse(T->rchild);
}
}
后序遍历(左子树→右子树→根结点)
层序遍历(对二叉树中的结点层数从上往下,同一层结点从左向右的顺序进行)
void layerOrderTraverse(BiTree T)
{
BiTree p;
queue<BiTree>q;
if(T != NULL)
{
q.push(T); //将根结点的指针入队列
while(!q.empty())
{
p = q.front(); //取出队头元素
q.pop(); //从队列中删除队头元素
visit(p); //访问p指向的结点元素
if(p ->lchild != NULL)
{
q.push(p->lchild); //将p结点的左孩子结点指针入队列
}
if(p->rchild != NULL)
{
q.push(p->rchild);
}
}
}
}
哈夫曼树和哈夫曼编码
二叉排序树
二叉排序树的性质:
1、若它的左子树不为空,则左子树上的所有结点的值均小于根结点的值
2、若它的右子树不为空,则右子树上的所有结点的值均大于根结点的值
3、二叉排序树的左右子树也是二叉排序树
如图
给定一个关键字key,在二叉排序树T中查找该关键字
BiTree SearchBST(BiTree T,dataType key)
{
if(T == NULL)
{
return NULL;
}
if(T->data == key)
{
retrun T;
}
if(key < T->data)
{
return SearchBST(T->lchild,key);
}
else
{
retrun SearchBST(T->rchild,key);
}
}
栈(Stack)
先进后出
栈顶(Top):栈的表尾,即插入和删除数据的地方(表头称为栈底)
栈的初始化
typedef struct
{
ElemType *base;
ElemType *top;
int stacksize; //长度
}sqStack;
int initStack(sqStack *s)
{
s->base = (ElemType *)malloc(10*sizeof(ElemType));
if(! s->base)
{
return 0;
}
s->top =s->base;
s->stacksize = 10;
return 1;
}
入栈
int Push(sqStack *p,ElemType e)
{
if(s->top - s->base >= s->stacksize) //栈满追加空间
{
s->base = (ElemType *)realloc(s->base,(s->stacksize + 10) * sizeof(ElemType));
if(!s->base)
{
return 0;
}
s->top = s->base + s->stacksize;
s->stacksize = s->stacksize + 10;
}
*(s->top) = e;
s->top ++;
return 1;
}
出栈
int Pop(sqStack *s,ElemType *e)
{
if(s->top == s->base)
{
return 0;
}
*e = * --(s-top);
return 1;
}
队列(Queue)
先进先出
队尾插入数据,队头取出数据
初始化队列
#define SIZE 100
struct Queue
{
int data[SIZE]; //存放数据
int front; //队头指针
int rear; //队尾指针
};
typedef struct Queue queue;
void InitQueue(queue **q)
{
if (NULL == q)
{
return ;
}
*q = (queue *)malloc(sizeof(queue));
if (NULL == *q)
{
return ;
}
(*q)->rear = (*q)->front = 0;
}
进队
int EnterQueue(queue *q, int e)
{
if(NULL == q)
{
return FAILURE;
}
if((q->rear + 1) % SIZE == q->front) //判断是否队满
{
return FAILURE;
}
q->data[q->rear] = e;
q->rear = (q->rear + 1) % SIZE; //防止rear越界
return SUCCESS;
}
出队(只能删除,不能遍历)
int DelQueue(queue *q)
{
if (NULL == q)
{
return FAILURE;
}
if (q->rear == q->front) //空队
{
return FAILURE;
}
int e = q->data[q->front]; //记录队头元素
q->front = (q->front + 1) % SIZE;
return e;
}
销毁队列
int DestroyQueue(queue **q)
{
if (NULL == q)
{
return FAILURE;
}
free(*q);
*q = NULL;
return SUCCESS;
}