• <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现


      栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO)。栈能够将递归问题转化为非递归问题,这是它的一个重要特性。除了FILO、FIFO这样的最普遍存取方式外,还有一些扩展的数据结构,如双端队列、双栈、超队列、超栈等,它们是一种扩展与变异结构。

      线性表有顺序存储和链接存储两类,这是针对计算机的线性存储空间作出的分类。前者可以是数组,后者可以是链表。字符串是线性表最常见的应用。

      这里我用C语言实现了一个基于数组环形队列,它具有固定的队列空间。相比于链表实现,它非常小巧和高效,特别是在负载可预计的情况下。

    //fifo.h
    #ifndef __FIFO_H__
    #define __FIFO_H__
    
    #define FIFO_LENGTH 20
    #define EMPTY    0x00
    #define FULL    0x01
    #define NORMAL  0x02
    
    typedef struct require_fifo{
        int item[FIFO_LENGTH];
        int read_ptr;
        int write_ptr;
        int flag;
    }fifo;
    
    extern fifo* fifo_create(void);
    extern void fifo_destroy(fifo* fifo_ptr);
    extern void fifo_in(fifo* fifo_ptr, int data);
    extern int fifo_out(fifo* fifo_ptr);
    
    #endif
    //fifo.c
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <memory.h>
    #include "fifo.h"
    
    fifo* fifo_create(void);
    void fifo_destroy(fifo* fifo_ptr);
    void fifo_in(fifo* fifo_ptr, int data);
    int fifo_out(fifo* fifo_ptr);
    
    fifo* fifo_create(void){
        fifo *fifo_ptr = malloc(sizeof(fifo));
        memset(fifo_ptr, 0, sizeof(fifo));
        fifo_ptr->write_ptr = 0;
        fifo_ptr->read_ptr = 0;
        fifo_ptr->flag = EMPTY;
        return fifo_ptr;
    }
    
    void fifo_destroy(fifo* fifo_ptr){
        free(fifo_ptr);
        printf("destroy fifo 
    ");
    }
    
    void fifo_in(fifo* fifo_ptr, int data){
        if(fifo_ptr->flag != FULL ){
            fifo_ptr->item[fifo_ptr->write_ptr] = data;
            fifo_ptr->write_ptr ++;
            fifo_ptr->write_ptr %= FIFO_LENGTH;
            if((fifo_ptr->write_ptr - fifo_ptr->read_ptr) == -1){
                fifo_ptr->flag = FULL;
            }else{
                fifo_ptr->flag = NORMAL;
            }
            //printf("write_ptr = %d 
    ", fifo_ptr->write_ptr);
        }else{
            printf("fifo is full, write invalide
    ");
        }
    }
    
    int fifo_out(fifo* fifo_ptr){
        int data = 0;
    
        if(fifo_ptr->flag != EMPTY){
            data = fifo_ptr->item[fifo_ptr->read_ptr];
            fifo_ptr->read_ptr ++;
            fifo_ptr->read_ptr %= FIFO_LENGTH;
            if((fifo_ptr->write_ptr - fifo_ptr->read_ptr) == 0){
                fifo_ptr->flag = EMPTY;    
            }
            //printf("read_ptr = %d 
    ", fifo_ptr->read_ptr);
            return data;
        }else{
            printf("fifo is empty, read invalide
    ");
            return -1;
        }
    
        return -1;
    }

      我们可以写一个测试代码来测试它的性能:

    #include <stdio.h>
    #include <pthread.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include "../fifo.h"
    
    pthread_mutex_t lock_fifo;
    fifo* myfifo;
    
    void * producer_thread1(void *pin){
        pin = NULL;
        while(1){
            pthread_mutex_lock(&lock_fifo);
            fifo_in(myfifo, 1);
            pthread_mutex_unlock(&lock_fifo);
            printf("producer1 put 1 into myfifo
    ");
            usleep(2000000);
        }
            return((void*)0);
    }
    
    void * producer_thread2(void *pin){
        pin = NULL;
        while(1){
            pthread_mutex_lock(&lock_fifo);
            fifo_in(myfifo, 2);
            pthread_mutex_unlock(&lock_fifo);
            printf("producer2 put 2 into myfifo
    ");
            usleep(1500000);
        }
            return((void*)0);
    }
    
    void * consumer_thread1(void *pin){
        int require = 0;
        pin = NULL;
        
        while(1){
            pthread_mutex_lock(&lock_fifo);
            require = fifo_out(myfifo);
            pthread_mutex_unlock(&lock_fifo);
            printf("    consumer1 get %d form myfifo
    ", require);
            usleep(1000000);
        }
            return((void*)0);
    }
    
    void * consumer_thread2(void *pin){
        int require = 0;
        pin = NULL;
        
        while(1){
            pthread_mutex_lock(&lock_fifo);
            require = fifo_out(myfifo);
            pthread_mutex_unlock(&lock_fifo);
            printf("    consumer2 get %d form myfifo
    ", require);
            usleep(1000000);
        }
            return((void*)0);
    }
    
    void keyboard_exit(int signo){
        printf("exit by keyboard 
    ");
        fifo_destroy(myfifo);
        _exit(0);
    }
    
    int main(){
        pthread_t th_producer1, th_producer2, th_consumer1, th_consumer2;
        void * ret;
        
        pthread_mutex_init(&lock_fifo, NULL);
        myfifo = fifo_create();
        signal(SIGINT, keyboard_exit);
        pthread_create(&th_producer1, NULL, producer_thread1, 0);    
        pthread_create(&th_producer2, NULL, producer_thread2, 0);    
        pthread_create(&th_consumer1, NULL, consumer_thread1, 0);    
        pthread_create(&th_consumer2, NULL, consumer_thread2, 0);    
        
        pthread_join(th_producer1, &ret);
        pthread_join(th_producer2, &ret);
        pthread_join(th_consumer1, &ret);
        pthread_join(th_consumer2, &ret);
    
        while(1){
            printf("thread error
    ");
        }
        return 1;
    }

      写一个gcc的Makefile文件来编译链接:

    CC = gcc
    CFLAGS := -g -Wall 
    LIB := -lpthread 
    OBJ = ../fifo.o ./test.o
    all: demo
    
    demo:test fifo
        $(CC) $(CFLAGS) -o ./demo $(OBJ) $(LIB)
    
    test:
        $(CC) $(CFLAGS) -o ./test.o -c ./test.c
    fifo:
        $(CC) $(CFLAGS) -o ../fifo.o -c ../fifo.c
    
    clean:
        rm ./test.o ./demo ../fifo.o
    
    
    .PHONY: $(PHONY) clean

      在test目录下运行./demo。

      输出结果:

                                write_ptr = 1 
    producer1 put 1 into myfifo
                                write_ptr = 2 
    producer2 put 2 into myfifo
                                read_ptr = 1 
        consumer1 get 1 form myfifo
                                read_ptr = 2 
        consumer2 get 2 form myfifo
    fifo is empty, read invalide
        consumer1 get -1 form myfifo
    fifo is empty, read invalide
        consumer2 get -1 form myfifo
                                write_ptr = 3 
    producer2 put 2 into myfifo
                                write_ptr = 4 
    producer1 put 1 into myfifo
                                read_ptr = 3 
        consumer1 get 2 form myfifo
                                read_ptr = 4 
        consumer2 get 1 form myfifo
                                write_ptr = 5 
    producer2 put 2 into myfifo
                                read_ptr = 5 
    。。。。
    。。。。
    ^Cexit by keyboard 
    destroy fifo 
  • 相关阅读:
    cloud-init 手动调试及问题解决
    深入理解openstack网络架构(四)
    深入理解openstack网络架构(三)
    深入理解openstack网络架构(二)
    深入理解openstack网络架构(一)
    ovs总结与常用命令
    如何debug cloud-init
    nova snapshot
    Openstack并行性能加速
    Nova 是如何统计 OpenStack 计算资源
  • 原文地址:https://www.cnblogs.com/andrew-wang/p/3731788.html
Copyright © 2020-2023  润新知