通用棧

棧是一種用得比較多的數據結構,用處很廣。但很多時候,棧中的元素是不一樣的。那如何寫一個通用的棧呢。在C++中有模板,那如何用C實現通用的棧呢。

在C語言中,不同的數據類型,佔用的字節數不一樣。參考qsort對不同數據類型的排序方法,可以得知,使用一個指針,以及此類型的大小即可。

具體的請參考以下代碼實現。

/*實現通用的棧結構
 */

#include <stdio.h>


typedef struct
{
	char *base, *top;
	int item_size; //棧中每個元素所佔的字節數。
	int item_num;
}stack;

/* 創建含有item_num個元素,每個元素佔有item_size個字節數的棧
 * 返回棧的指針
 * */
stack * create_stack(stack *s, int item_size, int item_num);

/* 釋放棧空間 */
void free_stack(stack *s);

/* 判斷棧是否已滿 */
int is_full(stack *s);

/* 判斷棧是否爲空 */
int is_empty(stack *s);

/* push item 所指向的元素進棧*/
void push(stack *s, const void *item);

void pop(stack *s, void *item);

//方便操作的宏定義
#define PUSH(s,e) do {\
	push(&s, (char*)&e);\
	}while(0);

#define POP(s,e) do{\
	pop(&s, (char*)&e);\
}while(0);

int main()
{
	stack s;
	create_stack(&s, sizeof(char), 10);

	char c;
	
	c = 'a';
	PUSH(s, c);

	c = 'b';
	PUSH(s, c);

	c = 'c';
	PUSH(s, c);

	c = 0;
	POP(s, c);
	printf("%c\n", c);

	POP(s, c);
	printf("%c\n", c);

	//pop(&s, c);
	POP(s, c);
	printf("%c\n", c);

	free(&s);

	return 0;
}


/* 創建含有ele_num個元素,每個元素佔有item_size個字節數的棧
 * 返回棧的指針
 * */
stack * create_stack(stack *s, int item_size, int item_num)
{
	if (s == NULL) 
		return NULL;

	item_num = item_num>0 ? item_num : 1;
	s->base = s->top = (char*)malloc(item_size * item_num);
	s->item_num = item_num;
	s->item_size = item_size;

	if (s->base==NULL)
		return NULL;
	else
		return s;
}

/* 釋放棧空間 */
void free_stack(stack *s)
{
	free(s->base);
	s->base = s->top = NULL;
}

/* 判斷棧是否已滿 */
int is_full(stack *s)
{
	if ((s->top - s->base)/s->item_size >= s->item_num)
		return 1;
	else
		return 0;
}

/* 判斷棧是否爲空 */
int is_empty(stack *s)
{
	if (s->top - s->base == 0)
		return 1;
	else
		return 0;
}

void push(stack *s, const void *item)
{
	if (is_full(s))
		return;
	void *p = &item;

	memcpy(s->top, item, s->item_size);
	s->top += s->item_size;
} 


void pop(stack *s, void *item)
{
	if (is_empty(s))
		return;

	s->top -= s->item_size;
	memcpy(item, s->top, s->item_size);
} 
爲了更符合使用習慣,將pop和push函數經過宏封閉。


缺點:push時,不能是常量,如 push(s, 'a')這種,因爲取地址編譯不通過。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章