Classic Abstract Data Types--C
本文内容来自《pointers on C》
- 栈的接口
/* Interface for a stack module */ #define STACK_TYPE int void push(STACK_TYPE value); void pop(void); STACK_TYPE top(void); int is_empty(void); int is_full(void);
2.使用动态数组实现栈
/* a stack implemented with a dynamically allocated arry*/ static STACK_TYPE *stack; static size_t stack_size; static int top_element=-1; void create_stack(size_t size) { assert(stack_size==0); stack_size=size; stack=malloc(stack_size*sizeof(STACK_TYPE)); assert(stack!=NULL); } void destroy_stack(void) { assert(stack_size>0); stack_size=0; free(stack); stack=NULL; }
3.使用链表实现数组。好处是数组长度不受限制。
/*a stack implemented with a linked list*/ typedef struct STACK_NODE { STACK_TYPE value; struct STACK_NODE *next; }StackNode; static StackNode *stack; void destroy_stack(void) { while(!is_empty()) pop(); } void push(STACK_TYPE value) { StackNode *new_node; new_node=malloc(sizeof(StackNode)); assert(new_node!=NULL); new_node->value=value; new_node->next=stack; stack=new_node;//在前面插入 } void pop(void) { StackNode *first_node; assert(!is_empty()); first_node=stack; stack=first_node->next;//在前面删除 free(first_node); } STACK_TYPE top(void) { assert(is_empty()); return stack->value; } int is_empty(void) { return stack==NULL; } int is_full(void) { return FALSE; }
4.队列的接口。
/*Interface for a queue module*/ #include<stdlib.h> #define QUEUE_TYPE int void create_queue(size_t size); /*this applies only to the dynamically \ allocated array implementation*/ void destroy_queue(void); /*this applies only to the linked and dyn- \ amically allcoated array implementations.*/ void insert(QUEUE_TYPE value); void delete(void); QUEUE_TYPE first(void); int is_empty(void); int is_full(void);
5.队列静态数组的实现。为了更好的分清队列的空和满的情况,将数组的第一个元素不存值。即空时:rear+1%ARRAY_SIZE==front;
当满时:rear+2%ARRAY_SIZE==front;
/* A queue implemented with a static array */ #define QUEUE_SIZE 100 #define ARRAY_SIZE (QUEUE_SIZE+1) static QUEUE_TYPE queue[ARRAY_SIZE]; static size_t front=1; static size_t rear=0; void insert(QUEUE_TYPE value) { assert(!is_full()); rear=(rear+1)%ARRAY_SIZE; queue[rear]=value; } void delete(void) { assert(!is_empty()); front=(front+1)% ARRAY_SIZE; } QUEUE_TYPE first(void) { assert(!is_empty()); return queue[front]; } int is_empty(void) { return (rear+1)% ARRAY_SIZE== front; } int is_full(void) { return (rear + 2) % ARRAY_SIZE== front; }
6.2叉树的接口
/* Interface for a binary search tree module*/ #define TREE_TYPE int void insert(TREE_TYPE value); /* must not already exist in the tree*/ TREE_TYPE *find(TREE_TYPE value); /* pass the first argument*/ void pre_order_traverse(void (*callback)(TREE_TYPE value)); /* callback \ process node*/
7. 2叉树的静态数组实现。注意的是数组从0开始。下标计算如此:左孩子:2N;右孩子:2N+1;
/* A binary search tree implemented with a static array */ #define TREE_SIZE 100 #define ARRAY_SIZE (TREE_SIZE+1) static TREE_SIZE tree[ARRAY_SIZE]; static int left_child(int current) { return current*2; } static int right_child(int current) { return current*2+1; } void insert(TREE_TYPE value) { int current; assert(value!=0); /* zero indicates an unused node */ current=1; while(tree[current]!=0) { if(value<tree[current]) current=left_child(current); else { assert(value!=tree[current]); current=right_child(current); } assert(current<ARRAY_SIZE); } tree[current]=value; } TREE_TYPE *find(TREE_TYPE value) { int current; current=1; while(current<ARRAY_SIZE && tree[current]!=value) { if(value<tree[current]) current=left_child(current); else current=right_child(current); } if(current<ARRAY_SIZE) return tree+current; else return 0; } /* helper function; not a part of the clent's interface*/ static void do_pre_order_traverse(int current, \ void (*callback)(TREE_TYPE value)) { if(current<ARRAY_SIZE && tree[current]!=0) { callback(tree[current]); do_pre_order_traverse(left_child(current),callback); do_pre_order_traverse(right_child(current),callback); } } void pre_order_traverse(void (*callbace)(TREE_TYPE value)) { do_pre_order_traverse(1,callbace); }
8. 2叉树的链表实现
/* A binary search tree implemented by linking dynamically allocated*/ typedef struct TREE_NODE { TREE_TYPE value; struct TREE_NODE *left; struct TREE_NODE *right; }TreeNode; static TreeNode *tree; void insert(TREE_TYPE value) { TreeNode *current; TreeNode **link;//link是指向树节点指针的指针 link=&tree; while((current=*link)!=NULL) { if(value<current->value) link=¤t->left; else { assert(value!=current->value); link=¤t->right; } } current =malloc(sizeof(TreeNode)); assert(current!=NULL); current->value=value; current->left=NULL; current->right=NULL; *link=current; } TREE_TYPE *find(TREE_TYPE value) { TreeNode *current; current=tree; while(current!=NULL && current->value!=value) { if(value<current->value) current=current->left; else current=current->right; } if(current!=NULL) return ¤t->value; else return NULL; } static void do_pre_order_traverse(TreeNode *current, \ void (*callback)(TREE_TYPE value)) { if(current!=NULL) { callback(current->value); do_pre_order_traverse(current->left,callback); do_pre_order_traverse(current->right,callback); } } void pre_order_traverse(void(*callback)(TREE_TYPE value)) { do_pre_order_traverse(tree,callback); }
9.栈(使用#define适用多类型)的接口。 ##:表示连接功能;\:表示转义换行符
/*ADTs of stack*/ #include<assert.h> #define GENERIC_STACK(STACK_TYPE,SUFFIX,STACK_SIZE) \ static STACK_TYPE stack##SUFFIX[STACK_SIZE]; \ static int top_element##SUFFIX=-1; \ int is_empty##SUFFIX(void) \ { \ return top_element##SUFFIX==-1; \ } \ int is_full##SUFFIX(void) \ { \ return top_element##SUFFIX==STACK_SIZE-1; \ } \ void push##SUFFIX(STACK_TYPE value) \ { \ assert(!is_full##SUFFIX()); \ top_element##SUFFIX++; \ stack##SUFFIX[top_element##SUFFIX]=value; \ } \ void pop##SUFFIX(void) \ { \ assert(!is_empty##SUFFIX()); \ top_element##SUFFIX--; \ } \ STACK_TYPE top##SUFFIX(void) \ { \ assert(!is_empty##SUFFIX()); \ return stack##SUFFIX[top_element##SUFFIX]; \ }
10. 分别使用int和float测试该接口
/* A client that uses the generic stack module to create two stacks holding defferent types of data */ #include<stdlib.h> #include<stdio.h> #include"g_stack.h" GENERIC_STACK(int,_int,10); GENERIC_STACK(float,_float,5); int main() { push_int(5); push_int(22); push_int(15); push_int(21); push_float(25.4); push_float(-20.1); while(!is_empty_int()) { printf("popping %d\n",top_int()); pop_int(); } while(!is_empty_float()) { printf("popping %f\n",top_float()); pop_float(); } return EXIT_SUCCESS; }