需求:将一颗二叉树通过网络传输到给另一个客户端,并且在该客户端恢复为原始二叉树。
编码环境:i686-linux-gnu
编译器:gcc version 4.4.5
目录结构:tree.h tree.c save.c load.c Makefile
Makefile:
all: save.out load.out
%.out: %.o tree.o
gcc -o $@ $^
%.o: %.c tree.h
gcc -c $< -o $@ -Wall
clean:
rm -f *.o *.out
tree.h
#ifndef IVAN_TREE_H
#define IVAN_TREE_H
typedef int DataType;
typedef struct tree_node {
struct tree_node *left;
struct tree_node *right;
DataType data;
}tree_node;
tree_node *tree_init(void);
void tree_draw(tree_node *);
int tree_save(const char *, tree_node *);
tree_node *tree_load(const char *);
#endif
tree.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#define BUFSIZE 32
static inline int inser__(tree_node **root, DataType data)
{
tree_node *node;
if (*root == NULL) {
node = malloc(sizeof(*node));
if (node == NULL) {
return -1;
}
node->data = data;
node->left = NULL;
node->right = NULL;
*root = node;
return 0;
}
if (data < (*root)->data)
return inser__(&(*root)->left, data);
if (data > (*root)->data)
return inser__(&(*root)->right, data);
return 0;
}
tree_node *tree_init(void)
{
DataType array[] = {4, 3, 7, 1, 2, 9, 8, 6, 10, 5};
tree_node *root = NULL;
int arraylen = sizeof(array) / sizeof(*array);
int i;
int ret;
for (i = 0; i < arraylen; i++) {
ret = inser__(&root, array[i]);
}
return (ret == -1) ? NULL : root;
}
static inline void draw__(tree_node *root, int level)
{
int i;
if (root == NULL)
return;
if (root->right != NULL)
draw__(root->right, level + 1);
for (i = 0; i < level; i++)
printf(" ");
printf("%hhd\n", root->data);
if (root->left != NULL)
draw__(root->left, level + 1);
}
void tree_draw(tree_node *root)
{
draw__(root, 0);
}
static inline int save__(int fd, tree_node *root)
{
char buf[BUFSIZE];
int ret;
write(fd, "(", 1);
if (root == NULL) {
write(fd, ")", 1);
return 0;
}
ret = snprintf(buf, BUFSIZE, "%d", root->data);
write(fd, buf, ret);
write(fd, " ", 1);
save__(fd, root->left);
save__(fd, root->right);
write(fd, ")", 1);
return 0;
}
int tree_save(const char *path, tree_node *root)
{
int fd;
int ret;
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
return -1;
ret = save__(fd, root);
close(fd);
return ret;
}
static int get_data(int fd)
{
char buf[BUFSIZE];
int i;
read(fd, buf, 1);
if (buf[0] == ')')
return 0;
for (i = 1; ;i++) {
read(fd, buf + i, 1);
if (!isdigit(buf[i]))
break;
}
return atoi(buf);
}
static inline tree_node *load__(int fd)
{
char buf[BUFSIZE];
int ret;
tree_node *root;
read(fd, buf, 1); /*read '('*/
ret = get_data(fd);
if (ret == 0)
return NULL;
root = malloc(sizeof(*root));
root->data = ret;
root->left = load__(fd);
root->right = load__(fd);
read(fd, buf, 1); /*read ')'*/
return root;
}
tree_node *tree_load(const char *path)
{
int fd;
tree_node *root;
fd = open(path, O_RDONLY);
root = load__(fd);
return root;
}
save.c
#include <stdio.h>
#include "tree.h"
int main(void)
{
tree_node *root;
root = tree_init();
tree_draw(root);
tree_save("./tmp", root);
return 0;
}
load.c
#include <stdio.h>
#include "tree.h"
int main(void)
{
tree_node *root;
root = tree_load("./tmp");
tree_draw(root);
return 0;
}