C 实现树行结构及操作,不能用堆(heap)
这是爱立信发的编程题目(要求用ANSI C实现):
You have to develop a solution for a dynamic tree of objects without using heap memory (i.e. without using malloc/free). As memory for your data, you are given a statically allocated buffer of some length N. For the tree you have to design the data structures, the tree structure itself has only one root. Each node of the tree may have multiple children. The data in a node (except the root) is given by the triple (int child_node_id, char* string, int string_length). Develop user-friendly methods to perform insert_node_as_child_of, find_node_given_path_from_root, remove_node_given_path_from_root. It might/will be necessary that you have to make suitable assumptions to complete the solutions. State clearly these assumptions.
既然不让用heap,我能想到的就是用数组来表示树了,不知到这样做行不行。我的解决方案如下:(请高手帮忙看一下是否正确)
1. 理论依据:
1) The stack is a place in the computer memory where all the variables that are declared and initialized before runtime are stored. The heap is the section of computer memory where all the variables created or initialized at runtime are stored.
2) (来自Wikipedia-binary tree) Binary trees can also be stored as an implicit data structure in arrays, and if the tree is a complete binary tree, this method wastes no space. In this compact arrangement, if a node has an index i, its children are found at indices 2i + 1(for the left child) and 2i + 2(for the right), while its parent (if any) is found at index (assuming the root has index zero).
2. 我的代码如下:
/*
* My assumption is as follow:
* 1. the tree is binary tree which means every node of the tree have at most two child nodes
* 2. the root node is the first one of the array.
* 3. the id of child node must be greater than 0 as integer.
* 4. the default value of root id is 0
*/
#include <stdio.h>
#include <string.h>
#define TREE_LENGTH 50 /* the length of the tree */
typedef struct tree_node T_Node;
/*
*the definition of the tree node
*/
struct tree_node{
int child_node_id; /* the identifier of node */
char *string; /* the string content */
int string_length; /* the length of the string */
};
/* the definition of the tree */
static T_Node Tree[TREE_LENGTH];
/*
* Description: Check the parent node whether has a available position for child that will be inserted
* return the available position of node on success or -1 on failure
*/
int get_child_opening(int parent_id){
if(parent_id>=0 && find_node(parent_id)!=-1){
if(Tree[parent_id*2+1].child_node_id==0){
return (parent_id*2+1);
}
else if(Tree[parent_id*2+2].child_node_id==0){
return (parent_id*2+2);
}
else{
return -1;
}
}
return -1;
}
/*
* Description: get the position of the last node in the tree
*/
int get_end_position(){
int i=0; /* the current position */
int j=0; /* the position of last child*/
while(i<=j && j<=TREE_LENGTH){
if(Tree[i*2+2].child_node_id!=0){
j=i*2+2;
}
else if(Tree[i*2+1].child_node_id!=0){
j=i*2+1;
}
i++;
}
if(j>TREE_LENGTH){
j=TREE_LENGTH;
}
return j;
}
/*
* Description: insert a node as a child of specific parent node
* return 1 on success or 0 on failure
*/
int insert_node(int parent_id,int childid,char *str){
int n=get_child_opening(parent_id);
if(n!=-1 && find_node(childid)==-1){
Tree[n].child_node_id=childid;
Tree[n].string=str;
Tree[n].string_length=strlen(str);
}
return 0;
}
/*
* Description: remove a specific child
* return 1 on success or 0 on failure
*/
int remove_node(int id){
int i=find_node(id);
if(i!=-1){
Tree[i].child_node_id=0;
Tree[i].string=NULL;
Tree[i].string_length=0;
}
return 1;
}
/*
* Description: find the specific childe
* return the position of the child on success or -1 on failure
*/
int find_node(int id){
int i=0; /* the current position */
while(i<=get_end_position()){
if(Tree[i].child_node_id==id){
return i;
}
i++;
}
return -1;
}
/*
* Description: print the tree for the purpose of test
*/
void print_tree(){
int i=0; /* the current position */
while(i<=get_end_position()){
printf("index:%d|node_id:%d|strng:%s|string_length:%d\n",
i,Tree[i].child_node_id,Tree[i].string,Tree[i].string_length);
i++;
}
printf("end position:%d\n",get_end_position());
}
/*
* Description: main functin for the purpose of test
*/
int main(){
insert_node(0,1,"aaaaaaaa");
insert_node(0,2,"bbbbbbbb");
insert_node(8,3,"cccccccc"); /* no such parent */
insert_node(0,4,"dddddddd"); /* no availabe position for such child */
insert_node(0,2,"eeeeeeee"); /* insert a existing child id */
remove_node(1); /* remove left child*/
//remove_node(2); /* remove right child*/
//remove_node(10); /* remove invalid child */
print_tree();
return 0;
}
* My assumption is as follow:
* 1. the tree is binary tree which means every node of the tree have at most two child nodes
* 2. the root node is the first one of the array.
* 3. the id of child node must be greater than 0 as integer.
* 4. the default value of root id is 0
*/
#include <stdio.h>
#include <string.h>
#define TREE_LENGTH 50 /* the length of the tree */
typedef struct tree_node T_Node;
/*
*the definition of the tree node
*/
struct tree_node{
int child_node_id; /* the identifier of node */
char *string; /* the string content */
int string_length; /* the length of the string */
};
/* the definition of the tree */
static T_Node Tree[TREE_LENGTH];
/*
* Description: Check the parent node whether has a available position for child that will be inserted
* return the available position of node on success or -1 on failure
*/
int get_child_opening(int parent_id){
if(parent_id>=0 && find_node(parent_id)!=-1){
if(Tree[parent_id*2+1].child_node_id==0){
return (parent_id*2+1);
}
else if(Tree[parent_id*2+2].child_node_id==0){
return (parent_id*2+2);
}
else{
return -1;
}
}
return -1;
}
/*
* Description: get the position of the last node in the tree
*/
int get_end_position(){
int i=0; /* the current position */
int j=0; /* the position of last child*/
while(i<=j && j<=TREE_LENGTH){
if(Tree[i*2+2].child_node_id!=0){
j=i*2+2;
}
else if(Tree[i*2+1].child_node_id!=0){
j=i*2+1;
}
i++;
}
if(j>TREE_LENGTH){
j=TREE_LENGTH;
}
return j;
}
/*
* Description: insert a node as a child of specific parent node
* return 1 on success or 0 on failure
*/
int insert_node(int parent_id,int childid,char *str){
int n=get_child_opening(parent_id);
if(n!=-1 && find_node(childid)==-1){
Tree[n].child_node_id=childid;
Tree[n].string=str;
Tree[n].string_length=strlen(str);
}
return 0;
}
/*
* Description: remove a specific child
* return 1 on success or 0 on failure
*/
int remove_node(int id){
int i=find_node(id);
if(i!=-1){
Tree[i].child_node_id=0;
Tree[i].string=NULL;
Tree[i].string_length=0;
}
return 1;
}
/*
* Description: find the specific childe
* return the position of the child on success or -1 on failure
*/
int find_node(int id){
int i=0; /* the current position */
while(i<=get_end_position()){
if(Tree[i].child_node_id==id){
return i;
}
i++;
}
return -1;
}
/*
* Description: print the tree for the purpose of test
*/
void print_tree(){
int i=0; /* the current position */
while(i<=get_end_position()){
printf("index:%d|node_id:%d|strng:%s|string_length:%d\n",
i,Tree[i].child_node_id,Tree[i].string,Tree[i].string_length);
i++;
}
printf("end position:%d\n",get_end_position());
}
/*
* Description: main functin for the purpose of test
*/
int main(){
insert_node(0,1,"aaaaaaaa");
insert_node(0,2,"bbbbbbbb");
insert_node(8,3,"cccccccc"); /* no such parent */
insert_node(0,4,"dddddddd"); /* no availabe position for such child */
insert_node(0,2,"eeeeeeee"); /* insert a existing child id */
remove_node(1); /* remove left child*/
//remove_node(2); /* remove right child*/
//remove_node(10); /* remove invalid child */
print_tree();
return 0;
}