一 树的基本概念
1.树的定义
n个节点的集合,有且只有一个根节点,其它节点可以看成m颗互不相交的子树,它呈现的一种层次结构
2.度数
(1)节点度数:拥有的子树的个数
(2)树的度数:最大的节点度数
(3)节点的层数:规定根节点的层数为1,子节点的层数为其父节点层数加1
(4)树的高度:最大的节点层数
(5)树叶节点:没有子节点的节点
3.二叉树定义
在这个树中,每个节点最多有两个子节点
(1)满二叉树
(2)完全二叉树
4.完全二叉树
特点:节点可以连续编号(从上到下,从左到右)
规律:
n个节点的完全二叉树,序号为k的节点
左孩子:存在条件 2*k <= n,编号2 * k
右孩子:存在条件 2*k + 1 <= n,编号2 * k + 1
5.二叉树的节点数据结构
typedef struct bnode
{
DATATYPE data; //存放数据
struct bnode *lchild; //记录左孩子位置
struct bnode *rchild; //记录右孩子位置
}btree_t;
二叉树的创建
#ifndef _HEAD_H_
#define _HEAD_H_
#define N 5
typedef struct bnode
{
char data;
struct bnode *lchild;
struct bnode *rchild;
}btree_t;
typedef btree_t * DATATYPE;
//链表节点的类型
typedef struct node
{
DATATYPE data;
struct node *next;
}LinkNode;
///////////////////////////////////////////////////////////////////
typedef struct
{
LinkNode *front;
LinkNode *rear;
}LinkQueue;
extern LinkQueue *create_linkqueue();
extern int is_empty_linkqueue(LinkQueue *q);
extern int enter_linkqueue(LinkQueue *q,DATATYPE data);
extern DATATYPE delete_linkqueue(LinkQueue *q);
#endif
create_binarytree(buf,1)
|
root = malloc_bnode(buf[1]);
if(2 * 1 <= 5)
root->lchild = create_binarytree(buf,2);
|
root = malloc_bnode(buf[2]);
if(2 * 2 <= 5)
root->lchild = create_binarytree(buf,4);
|
root = malloc_bnode(buf[4]);
if(2 * 4 <= 5)
...
if(2 * 4 + 1 <= 5)
...
return root;
if(2 * 2 + 1 <= 5)
root->rchild = create_binarytree(buf,5);
|
root = malloc_bnode(buf[5])
if(2 * 5 <= 5)
...
if(2 * 5 + 1 <= 5)
...
return root
return root;
if(2 * 1 + 1<= 5)
root->rchild = create_binarytree(buf,3);
|
root = malloc_bnode(buf[3]);
if(2 * 3 <= 5)
...
if(2 * 3 + 1 <= 5)
..
return root;
return root
二叉树
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
btree_t *malloc_bnode(char data)
{
btree_t *tree;
tree = (btree_t *)malloc(sizeof(btree_t));
tree->data = data;
tree->lchild = tree->rchild = NULL;
return tree;
}
//char buf[] <=> char *buf
btree_t *create_binarytree(char buf[],int num)
{
btree_t *root;
root = malloc_bnode(buf[num]);
if(2 * num <= N)
{
root->lchild = create_binarytree(buf,2 * num);
}
if(2 * num + 1 <= N)
{
root->rchild = create_binarytree(buf,2 * num + 1);
}
return root;
}
void pre_order(btree_t *root)
{
if(root == NULL)
return;
printf("%c ",root->data);
pre_order(root->lchild);
pre_order(root->rchild);
return ;
}
void in_order(btree_t *root)
{
if(root == NULL)
return;
in_order(root->lchild);
printf("%c ",root->data);
in_order(root->rchild);
return;
}
int no_order(btree_t *root)
{
btree_t *temp;
LinkQueue *q = create_linkqueue();
enter_linkqueue(q,root);
while(!is_empty_linkqueue(q))
{
temp = delete_linkqueue(q);
printf("%c ",temp->data);
if(temp->lchild != NULL)
{
enter_linkqueue(q,temp->lchild);
}
if(temp->rchild != NULL)
{
enter_linkqueue(q,temp->rchild);
}
}
printf("\n");
return 0;
}
int main(int argc, const char *argv[])
{
btree_t *root;
char buf[] = {0,'a','b','c','d','e'};
root = create_binarytree(buf,1);
pre_order(root);
putchar('\n');
in_order(root);
putchar('\n');
no_order(root);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
LinkQueue *create_linkqueue()
{
LinkNode *head;
LinkQueue *q;
head = (LinkNode *)malloc(sizeof(LinkNode));
head->next = NULL;
q = (LinkQueue *)malloc(sizeof(LinkQueue));
q->front = q->rear = head;
return q;
}
int is_empty_linkqueue(LinkQueue *q)
{
return q->front == q->rear ? 1 : 0;
}
int enter_linkqueue(LinkQueue *q,DATATYPE data)
{
LinkNode *temp;
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
temp->next = NULL;
//让链表链接
q->rear->next = temp;
//更新rear到新的尾部节点
q->rear = temp;
return 0;
}
DATATYPE delete_linkqueue(LinkQueue *q)
{
LinkNode *temp;
if(is_empty_linkqueue(q))
{
printf("The LinkQueue is empty!\n");
return (DATATYPE)-1;
}
temp = q->front;
q->front = temp->next;
free(temp);
return q->front->data;
}
huffman树
#ifndef _HEAD_H_
#define _HEAD_H_
#define N 5
typedef struct hnode
{
char c;
int weight;
char code[256];
struct hnode *lchild;
struct hnode *rchild;
}htree_t;
typedef htree_t * DATATYPE;
//链表节点的类型
typedef struct node
{
DATATYPE data;
struct node *next;
}LinkNode;
///////////////////////////////////////////////////////////////////
typedef struct
{
LinkNode *front;
LinkNode *rear;
}LinkQueue;
extern LinkQueue *create_linkqueue();
extern int is_empty_linkqueue(LinkQueue *q);
extern int enter_linkqueue(LinkQueue *q,DATATYPE data);
extern DATATYPE delete_linkqueue(LinkQueue *q);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "head.h"
int calc_char_count(char *string,int count[])
{
char *p;
for(p = string; *p != '\0';p ++)
{
count[*p] ++;
}
return 0;
}
// 1 3 5
// 2
int insert_order_linkqueue(LinkQueue *lq,DATATYPE data)
{
LinkNode *temp;
LinkNode *q,*p;
LinkNode *head = lq->front;
q = head;
p = head->next;
while(p != NULL)
{
if(p->data->weight > data->weight)
break;
else{
p = p->next;
q = q->next;
}
}
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
temp->next = q->next;
q->next = temp;
//更新q->rear值,找到尾部节点
for(p = head;p->next != NULL;p = p->next);
lq->rear = p;
return 0;
}
htree_t *malloc_hnode(char c,int w)
{
htree_t *tree;
tree = (htree_t *)malloc(sizeof(htree_t));
memset(tree,0,sizeof(htree_t));
tree->c = c;
tree->weight = w;
tree->lchild = tree->rchild = NULL;
return tree;
}
LinkQueue *create_hffman_queue(int count[])
{
int i = 0;
htree_t *tree;
LinkQueue *q = create_linkqueue();
for(i = 0;i < 256;i ++)
{
if(count[i] != 0){
tree = malloc_hnode(i,count[i]);
insert_order_linkqueue(q,tree);
}
}
return q;
}
int is_onenode_linkqueue(LinkQueue *q)
{
return q->front->next == q->rear ? 1 : 0;
}
htree_t *create_huffman_tree(LinkQueue *q)
{
htree_t *newtree;
htree_t *ltree,*rtree;
/*
* 思路:
* ltree = delete_linkqueue(q);
* rtee = delete_linkqueue(q);
* 分配新节点空间,新节点权值是左和右权值相加之和,左右孩子ltree,rtee
* 新节点有序进队
*/
while(!is_onenode_linkqueue(q))
{
ltree = delete_linkqueue(q);
rtree = delete_linkqueue(q);
newtree = malloc_hnode('\0',ltree->weight + rtree->weight);
newtree->lchild = ltree;
newtree->rchild = rtree;
insert_order_linkqueue(q,newtree);
}
//出队返回树根节点
return delete_linkqueue(q);
}
char *gcode[256];
int no_order(htree_t *root)
{
htree_t *temp;
LinkQueue *q = create_linkqueue();
enter_linkqueue(q,root);
while(!is_empty_linkqueue(q))
{
temp = delete_linkqueue(q);
//printf("%c:%d ",temp->c,temp->weight);
if(temp->lchild == NULL && temp->rchild == NULL)
{
gcode[temp->c] = temp->code;
printf("%c:%s\n",temp->c,temp->code);
}
if(temp->lchild != NULL)
{
strcpy(temp->lchild->code,temp->code);
strcat(temp->lchild->code,"0");
enter_linkqueue(q,temp->lchild);
}
if(temp->rchild != NULL)
{
strcpy(temp->rchild->code,temp->code);
strcat(temp->rchild->code,"1");
enter_linkqueue(q,temp->rchild);
}
}
printf("\n");
return 0;
}
int compress_string(char *string,char *cbuf)
{
char *p;
for(p = string; *p != '\0';p ++)
{
strcat(cbuf,gcode[*p]);
}
return 0;
}
int main(int argc, const char *argv[])
{
char buf[1024];
int count[256] = {0};
char cbuf[1024] = {0};
LinkQueue *q;
htree_t *root;
// printf("Input string : ");
scanf("%s",buf);
calc_char_count(buf,count);
q = create_hffman_queue(count);
root = create_huffman_tree(q);
no_order(root);
compress_string(buf,cbuf);
printf("comress string : %s\n",cbuf);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
LinkQueue *create_linkqueue()
{
LinkNode *head;
LinkQueue *q;
head = (LinkNode *)malloc(sizeof(LinkNode));
head->next = NULL;
q = (LinkQueue *)malloc(sizeof(LinkQueue));
q->front = q->rear = head;
return q;
}
int is_empty_linkqueue(LinkQueue *q)
{
return q->front == q->rear ? 1 : 0;
}
int enter_linkqueue(LinkQueue *q,DATATYPE data)
{
LinkNode *temp;
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
temp->next = NULL;
//让链表链接
q->rear->next = temp;
//更新rear到新的尾部节点
q->rear = temp;
return 0;
}
DATATYPE delete_linkqueue(LinkQueue *q)
{
LinkNode *temp;
if(is_empty_linkqueue(q))
{
printf("The LinkQueue is empty!\n");
return (DATATYPE)-1;
}
temp = q->front;
q->front = temp->next;
free(temp);
return q->front->data;
}