两种实现数据结构中的栈(C语言)

为了学习数据结构中的栈,自己码了一下其常见的操作,代码如下:

/* 栈的实现 2 数组实现 结构体内定义数组 *******
 * 通过结构体内指针的移动
 */
typedef struct note  {
	char *base;                    /* 字符数组 */
	char *top;
	int size;
} stack;

/* 栈的实现 1 链表实现 *********
 * 通过结构体间指针传递
 */
typedef struct lnote {
	char c;
	struct lnote *next;
} Stack;

#include <stdio.h>
#include <stdlib.h>

#define Maxlen 20
/* 数组实现的函数 */
stack *create_stack(void);
void push_stack(stack *, char);
void print_stack(stack *);
char pop_stack(stack *);
void dispose_stack(stack *);

/* 链表实现的函数 */
Stack *Create_Stack(void);
void Push_Stack(Stack *, char);
void Print_stack(Stack *);
char Pop_Stack(Stack *);
void Dispose_Stack(Stack *);

int main()
{
	/***数组实现
	char x;
	stack *s;
	s = create_stack();
	push_stack(s,'a');
	push_stack(s,'b');
	x = pop_stack(s);
	push_stack(s,'c');
	print_stack(s);
	dispose_stack(s);
	*/
	/* 链表实现 */
	char x;
	Stack *head;
	head = Create_Stack();
	Push_Stack(head, 'a');
	Push_Stack(head, 'b');
	Push_Stack(head, 'c');
	x = Pop_Stack(head);
	Print_stack(head);
	Dispose_Stack(head);
	getchar();
	return 0;
}

/*********************链表的实现*******************/
/*
 *     初始化
 */
Stack *Create_Stack(void)
{
	Stack *head;
	head = (Stack *)(malloc(sizeof(Stack)));
	if (head == NULL)
		printf("Out of space");
	head->next = NULL;
	return head;
}

/*
 *     压栈         ***************版本一不含头结点  错误的******
 */
//void Push_Stack(Stack *s, char a)//Push_Stack_w/o_head(Stack *s, char a)
//{
//	Stack *p;
//	p = (Stack *)(malloc(sizeof(Stack)));
//	if (p == NULL) {
//		printf("Out of space");
//		return;
//	}
//	p->c = a;
//	p->next = s;
//	s = p;               /* 此时只改变了形参 s, 实参是没有变的,如果加入头结点就可以用指针改变栈顶了 */
//	printf("%c\n",s->c);
//}

/*
 *     压栈         ********不含头结点 ******
 */
void Push_Stack(Stack *s, char a)
{
	Stack *p;
	p = (Stack *)(malloc(sizeof(Stack)));
	if (p == NULL) {
		printf("Out of space");
		return;
	}
	p->c = a;
	p->next = s->next;                            /* 采用链表的前插法 */
	s->next = p;                                  /* 用指针改变栈顶了 */
}

/*
 *     打印
 */
void Print_stack(Stack *s)
{
	Stack *p;
	p = s->next;
	while (p) {
		printf ("%c\n",p->c);
		p = p->next;
	}
}

/*
 *     出栈
 */
char Pop_Stack(Stack *s)
{
	char temp;
	Stack *p;
	p = s->next;
	if(!p) {
		printf("Empty stack");
		return -1;
	}
	temp = s->c;
	s->next = p->next;                    /* 暂存以前的栈顶,以便释放 */
	free(p);
	return temp;
}

/*
 *     删除栈
 */
void Dispose_Stack(Stack *s)
{
	Stack *temp, *p;
	p = s->next;
	while(p) {
		temp = p->next;          /* 暂存下一个地址,因为如果释放s->next 后,下一个元素的地址就消失了 */
		free(p);
		p = temp;
	}
	free(s);
}
/********************************数组的实现************************************/
/*
 *     初始化
 */
stack *create_stack(void) {                               /* 返回一个空栈(指针) */
	stack *head;
	head = (stack *)(malloc(sizeof(stack)));              /* 如果是char类型的字符串,那么还要 *字符串的长度 *******/
	if (head == NULL)
		printf ("Out of space");                          /* 以上为指定栈的结构 */
	                         
	head->base = (char *)(malloc(Maxlen*sizeof(char)));   /* 以下为指定栈的数组 ********/
	if (head->base == NULL)
		printf ("Out of space");
	head->top = head->base;                               /* 空栈:栈顶和栈底指向同一单元 *******/
	head->size = Maxlen;
	return head;
}

/*
 *     压栈
 */
void push_stack(stack *s, char a)
{
	if (s->top - s->base > s->size) {
		printf("Full stack");
		return;
	}
	*s->top++ = a;
}

/*
 *     出栈
 */
char pop_stack(stack *s)
{
	if (s->top == s->base)
		printf("Empty stack");
	s->top -=1;
	return *s->top;                        
}

void print_stack(stack *s)
{
	char *p;                                       /* 注意打印的时候要用指针变量 p 来控制指针的移动 不能用top 因为它会改变栈的结构 */
	p = s->top-1;
	while (p - s->base >= 0) {
		printf ("%c\n", *p--);
	}
}

/*
 *     释放栈
 */
void dispose_stack(stack *s)
{
	if (s) {
		free(s->base);             /* 和分配内存顺序相反,先释放数组,再释放结构体*/
		free(s);                   
	}
}


 

还有一些操作没有写上去,我认为这些应该差不多了。

希望互相学习,共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值