Classic Abstract Data Types--C

本文内容来自《pointers on C》
  1. 栈的接口
/*    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=&current->left;
            else
            {
                assert(value!=current->value);
                link=&current->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 &current->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;
}

 

posted @ 2014-05-16 16:55  哈士奇.银桑  阅读(184)  评论(0编辑  收藏  举报