数据结构之树

一  树的基本概念 

 

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;

}

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值