zoukankan      html  css  js  c++  java
  • 栈-链式存储

    链表实现栈




    创建3个文件:stackLinked.h、stackLinked.c、stackLinkedTest.c




    stackLinked.h
    #ifndef STACK_LINKED_H_
    #define STACK_LINKED_H_
    
    #ifdef __GNUC__
    	#define DEPRECATED __attribute__( (deprecated) )
    #elif defined(_MSC_VER)
    	#define DEPRECATED __declspec( deprecated )
    #else
    	#define DEPRECATED
    #endif
    
    #ifndef PTOI
    	#define PTOI( p ) ((int32_t)(int64_t)(p))
    #endif
    #ifndef ITOP
    	#define ITOP( i ) ((void *)(int64_t)(i))
    #endif
    
    #define ADT StackLinked
    
    // 功能: a与b的比较过程.
    // 参数: a, b.
    // 返回: a>b返回正数, a<b返回负数, 否则返回0.
    // 注意: a不为NULL且b为NULL,返回正数, a为NULL且b不为NULL,返回负数, a与b都为NULL,返回0.
    typedef int ( CompareFunc )( const void *a, const void *b );
    
    typedef struct StackLinked StackLinked;
    
    // 功能: 创建新的栈.
    // 参数: 无.
    // 返回: 新的栈.
    // 注意: 当内存分配失败时,将错误退出程序.
    extern ADT *newStackLinked( void );
    
    // 功能: 将用户数据压入到栈顶.
    // 参数: stack(栈对象的指针), data(用户数据).
    // 返回: 被压入栈顶的用户数据.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    extern void *pushStackLinked( ADT *stack, void *data );
    
    // 功能: 弹出栈顶用户数据.
    // 参数: stack(栈对象的指针).
    // 返回: 被弹出的栈顶的用户数据.
    // 注意: 当 stack 为NULL 或 空栈状态 时, 将错误退出程序.
    extern void *popStackLinked( ADT *stack );
    
    // 功能: 偷看栈顶的用户数据.
    // 参数: stack(栈对象的指针).
    // 返回: 栈顶的用户数据.
    // 注意: 当 stack 为NULL 或 空栈状态 时, 将错误退出程序.
    extern void *peekStackLinked( ADT *stack );
    
    // 功能: 偷看栈底的用户数据.
    // 参数: stack(栈对象的指针).
    // 返回: 栈底的用户数据.
    // 注意: 当 stack 为NULL 或 空栈状态 时, 将错误退出程序.
    extern void *peekBottomStackLinked( ADT *stack );
    
    // 功能: 栈中所有用户数据中是否包含了data.
    // 参数: stack(栈对象的指针), data(需查找的用户数据), cmp(比较函数的指针).
    // 返回: 包含data返回1, 否则返回0.
    // 注意: 当 stack 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int existStackLinked( ADT *stack, void *data, CompareFunc *cmp );
    
    // 功能: 从栈顶至栈底方向查找data.
    // 参数: stack(栈对象的指针), data(需查找的用户数据), cmp(比较函数的指针).
    // 返回: 包含data, 返回data所在位置, 否则返回-1.
    // 注意: 当 stack 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int32_t findStackLinked( ADT *stack, void *data, CompareFunc *cmp );
    
    // 功能: 从栈底至栈顶方向查找data.
    // 参数: stack(栈对象的指针), data(需查找的用户数据).
    // 返回: 包含data, 返回data所在位置, 否则返回-1, cmp(比较函数的指针).
    // 注意: 当 stack 为NULL 或 cmp 为NULL 时, 将错误退出程序.
    extern int32_t findTailStackLinked( ADT *stack, void *data, CompareFunc *cmp );
    
    // 功能: 栈实际已使用大小.
    // 参数: stack(栈对象的指针).
    // 返回: 栈实际已使用大小.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    extern int32_t sizeStackLinked( ADT *stack );
    
    // 功能: 空栈状态.
    // 参数: stack(栈对象的指针).
    // 返回: 是空栈返回1, 否则返回0.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    extern int emptyStackLinked( ADT *stsack );
    
    // 功能: 反转栈.
    // 参数: stack(栈对象的指针).
    // 返回: 无.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    extern void reversalStackLinked( ADT *stack );
    
    // 功能: 满栈状态.
    // 参数: stack(栈对象的指针).
    // 返回: 是满栈返回1, 否则返回0.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    // 被弃用的函数.
    extern DEPRECATED int fullStackLinked( ADT *stack );
    
    // 功能: 栈最大容量.
    // 参数: stack(栈对象的指针).
    // 返回: 栈最大容量.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    // 被弃用的函数.
    extern DEPRECATED int32_t capacityStackLinked( ADT *stack );
    
    // 功能: 清空栈.
    // 参数: stack(栈对象的指针).
    // 返回: 无.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    extern void clearStackLinked( ADT *stack );
    
    // 功能: 销毁栈.
    // 参数: stack(存放栈对象的指针的指针).
    // 返回: 无.
    // 注意: 当 stack 为NULL 时, 将错误退出程序.
    extern void delStackLinked( ADT **stack );
    
    #undef ADT
    
    #endif
    

    stackLinked.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include "stackLinked.h"
    
    
    // 功能: 打印错误信息后就错误退出程序.
    // 参数: expression(错误判断表达式), message(需打印的错误信息).
    // 返回: 无.
    // 注意: 当表达式 expression 为真时, 才触发.
    #define ERROR_EXIT( expression, message )                                    
    if( (expression) ) {                                                         
    	fprintf( stderr, "
    error location: file = %s, func = %s, line = %d.
    ", 
    	                       __FILE__, __func__, __LINE__ );                   
    	fprintf( stderr, "error  message: %s%s.
    a",                            
    	                       (message) != NULL ? (message) : __func__,         
    		                   (message) != NULL ? "" : " function error" );     
    	exit( EXIT_FAILURE );                                                    
    }
    
    #define ADT StackLinked
    
    
    typedef struct NodeStackLinked {
    	void *data;
    	struct NodeStackLinked *next;
    } Node;
    
    struct StackLinked {
    	int32_t size;
    	Node *prev; // 指向栈底.
    	Node *next; // 指向栈顶.
    };
    
    
    ADT *newStackLinked( void ) {
    	ADT *stack = NULL;
    
    	stack = calloc( sizeof(*stack), 1 );
    	ERROR_EXIT( !stack, NULL );
    
    	return stack;
    }
    
    void *pushStackLinked( ADT *stack, void *data ) {
    	Node *node = NULL;
    
    	ERROR_EXIT( !stack, NULL );
    	node = malloc( sizeof(*node) );
    	ERROR_EXIT( !node, NULL );
    	node->data = data;
    	node->next = stack->next;
    	stack->prev = !stack->prev ? node : stack->prev;
    	stack->next = node;
    	++stack->size;
    
    	return data;
    }
    
    void *popStackLinked( ADT *stack ) {
    	void *data = NULL;
    	Node *node = NULL;
    
    	ERROR_EXIT( !stack || stack->size < 1, NULL );
    	node = stack->next;
    	stack->prev = node != stack->prev ? stack->prev : NULL;
    	stack->next = node->next;
    	--stack->size;
    	data = node->data;
    	free( node );
    
    	return data;
    }
    
    void *peekStackLinked( ADT *stack ) {
    	ERROR_EXIT( !stack || stack->size < 1, NULL );
    
    	return stack->next->data;
    }
    
    void *peekBottomStackLinked( ADT *stack ) {
    	ERROR_EXIT( !stack || stack->size < 1, NULL );
    
    	return stack->prev->data;
    }
    
    int existStackLinked( ADT *stack, void *data, CompareFunc *cmp ) {
    	Node *n = NULL;
    
    	ERROR_EXIT( !stack || !cmp, NULL );
    	for( n = stack->next; n != NULL; n = n->next ) {
    		if( !cmp( n->data, data ) ) {
    			return 1;
    		}
    	}
    
    	return 0;
    }
    
    int32_t findStackLinked( ADT *stack, void *data, CompareFunc *cmp ) {
    	Node *n = NULL;
    	int32_t i = 0;
    
    	ERROR_EXIT( !stack || !cmp, NULL );
    	for( n = stack->next; n != NULL; n = n->next ) {
    		if( !cmp( n->data, data ) ) {
    			return i;
    		}
    		++i;
    	}
    
    	return -1;
    }
    
    int32_t findTailStackLinked( ADT *stack, void *data, CompareFunc *cmp ) {
    	Node *p1 = NULL, *p2 = NULL, *p3 = NULL;
    	int32_t ret = -1, i = 0;
    
    	ERROR_EXIT( !stack || !cmp, NULL );
    	// 3指针法反转链表.
    	for( p1 = NULL, p2 = stack->next; p2 != NULL; p2 = p3 ) {
    		p3 = p2->next;
    		p2->next = p1;
    		p1 = p2;
    	}
    	for( p3 = p1; p3 != NULL; p3 = p3->next ) {
    		if( !cmp( p3->data, data ) ) {
    			ret = i;
    			break;
    		}
    		++i;
    	}
    	// 3指针法再次反转链表, 恢复原顺序.
    	for( p2 = p1, p1 = NULL; p2 != NULL; p2 = p3 ) {
    		p3 = p2->next;
    		p2->next = p1;
    		p1 = p2;
    	}
    
    	return ret;
    }
    
    int32_t sizeStackLinked( ADT *stack ) {
    	ERROR_EXIT( !stack, NULL );
    
    	return stack->size;
    }
    
    int emptyStackLinked( ADT *stack ) {
    	ERROR_EXIT( !stack, NULL );
    
    	return stack->size < 1;
    }
    
    void reversalStackLinked( ADT *stack ) {
    	Node *p1 = NULL, *p2 = NULL, *p3 = NULL;
    
    	ERROR_EXIT( !stack, NULL );
    	stack->prev = stack->next;
    	for( p1 = NULL, p2 = stack->next; p2 != NULL; p2 = p3 ) { // 三指针法反转链表.
    		p3 = p2->next;
    		p2->next = p1;
    		p1 = p2;
    	}
    	stack->next = p1;
    }
    
    int fullStackLinked( ADT *stack ) {
    	ERROR_EXIT( !stack, NULL );
    
    	return 0;
    }
    
    int32_t capacityStackLinked( ADT *stack ) {
    	ERROR_EXIT( !stack, NULL );
    
    	return INT32_MAX;
    }
    
    void clearStackLinked( ADT *stack ) {
    	Node *current = NULL, *next = NULL;
    
    	ERROR_EXIT( !stack, NULL );
    	for( current = stack->next; current != NULL; current = next ) {
    		next = current->next;
    		free( current );
    	}
    	stack->size = 0;
    }
    
    void delStackLinked( ADT **stack ) {
    	Node *current = NULL, *next = NULL;
    
    	ERROR_EXIT( !stack, NULL );
    	if( !stack ) {
    		return;
    	}
    	for( current = stack[0]->next; current != NULL; current = next ) {
    		next = current->next;
    		free( current );
    	}
    	free( *stack );
    	*stack = NULL;
    }
    

    stackLinkedTest.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <time.h>
    #include "stackLinked.h"
    
    // a>b返回正数, a<b返回负数, 否则返回0.
    static int cmp( const void *a, const void *b ) {
    	return *(int32_t *) a - *(int32_t *) b;
    }
    
    int main( int argc, char *argv[] ) {
    	char *tf[] = {"false", "true"};
    	int32_t *a = NULL, n = 0;
    	int32_t i = 0, k = 0;
    	StackLinked *s = NULL;
    
    	srand( time( NULL ) );
    	printf( "please input array length: n = " );
    	scanf( "%d%*c", &n );
    	printf( "
    " );
    
    	a = malloc( sizeof(*a) * n );
    	for( i = 0; i < n; ++i ) {
    		a[i] = rand() % 322;
    		//a[i] = 1;
    	}
    
    	printf( "&s = %p, s = %p
    ", &s, s );
    	s = newStackLinked();
    	printf( "new: &s = %p, s = %p
    ", &s, s );
    
    	printf( "peek       = %d
    ", emptyStackLinked( s ) ? INT32_MIN : *(int32_t *) peekStackLinked( s ) );
    	printf( "peekBottom = %d
    ", emptyStackLinked( s ) ? INT32_MIN : *(int32_t *) peekBottomStackLinked( s ) );
    	printf( "size     = %d
    ", sizeStackLinked( s ) );
    	printf( "empty = %s
    ", tf[emptyStackLinked( s )]);
    	printf( "
    " );
    
    	for( i = 0; i < n; ++i ) {
    		printf( "push: %4d
    ", *(int32_t *) pushStackLinked( s, &a[i] ) );
    	}
    	printf( "
    " );
    
    	printf( "peek       = %d
    ", emptyStackLinked( s ) ? INT32_MIN : *(int32_t *) peekStackLinked( s ) );
    	printf( "peekBottom = %d
    ", emptyStackLinked( s ) ? INT32_MIN : *(int32_t *) peekBottomStackLinked( s ) );
    	printf( "size     = %d
    ", sizeStackLinked( s ) );
    	printf( "empty = %s
    ", tf[emptyStackLinked( s )] );
    	printf( "
    " );
    
    	//k = a[0];
    	k = rand();
    	printf( "exist &k(%d) = %s
    ", k, tf[existStackLinked( s, &k, cmp )] );
    	printf( "
    " );
    
    	k = a[0];
    	//k = rand();
    	printf( "find &k(%d) = %d
    ", k, findStackLinked( s, &k, cmp ) );
    	printf( "
    " );
    
    
    	//k = a[0];
    	k = rand();
    	printf( "findTile &k(%d) = %d
    ", k, findTailStackLinked( s, &k, cmp ) );
    	printf( "
    " );
    
    	//reversalStackLinked( s ); // 反转栈.
    
    	while( !emptyStackLinked( s ) ) {
    		printf( "pop: %4d
    ", *(int32_t *) popStackLinked( s ) );
    	}
    	printf( "
    " );
    
    	printf( "peek       = %d
    ", emptyStackLinked( s ) ? INT32_MIN : *(int32_t *) peekStackLinked( s ) );
    	printf( "peekBottom = %d
    ", emptyStackLinked( s ) ? INT32_MIN : *(int32_t *) peekBottomStackLinked( s ) );
    	printf( "size     = %d
    ", sizeStackLinked( s ) );
    	printf( "empty = %s
    ", tf[emptyStackLinked( s )] );
    	printf( "
    " );
    
    	delStackLinked( &s );
    	printf( "del: &s = %p, s = %p
    ", &s, s );
    
    	return EXIT_SUCCESS;
    }
    



  • 相关阅读:
    设计模式(08):结构型模式(二) 桥接模式(Bridge)
    设计模式(07):结构型模式(一) 适配器模式(Adapter)
    设计模式(06):创建型模式(五) 原型模式(Prototype)
    node.js获取cookie
    排序算法[转]
    Observer(观察者)设计模式[转]
    c#发送Http请求
    win+R下的命令
    display:inline、block、inline-block的区别
    Redis安装
  • 原文地址:https://www.cnblogs.com/hujunxiang98/p/12884000.html
Copyright © 2011-2022 走看看