数据结构之栈

决定采用何种方式来存储数据是非常重要的,这样便于检索数据时,数据会自动按照某种规定的顺序给出。

栈是检索数据的一种方式,它检索元素的顺序与存储元素的顺序相反。

栈:先进后出。

要把元素存储到栈中,就“压入”元素,要删除栈中的元素,就“弹出”元素。

有时候,可以通过检查栈顶的元素(而不是实际去删除它)来获取元素的某些信息。


实现栈的方式有很多,这里采用链表来实现。因为栈本身就是个链表,它与链表有相同的特性。


1,这是单链表的接口定义:

#ifndef _DLIST_H
#define _DLIST_H

#include <stdlib.h>

typedef struct DListElmt_
{
	void *data;
	struct DListElmt_ *next;
	struct DListElmt_ *prev;
}DListElmt;

typedef struct DList_
{
	int size;
	void (*destroy)(void *data);
	int (*match)(const void *key1,const void *key2);
	DListElmt *head;
	DListElmt *tail;
}DList;

void dlist_init(DList *list,void (*destroy)(void *data));

void dlist_destroy(DList *list);

int dlist_ins_next(DList *list,DListElmt *element,const void *data); //成功返回1,失败返回-1

int dlist_ins_prev(DList *list,DListElmt *element,const void *data); //成功返回0,失败返回-1

int dlist_remove(DList  *list,DListElmt *element,void **data);

#define dlist_size(list)  ((list)->size)
#define dlist_head(list)  ((list)->head)
#define dlist_tail(list)  ((list)->tail)
#define dlist_is_head(element)  ((element)->prev == NULL ? 1 : 0)
#define dlist_is_tail(element)  ((element)->next == NULL ? 1 : 0)
#define dlist_data(element)  ((element)->data)
#define dlist_next(element)  ((element)->next)
#define dlist_prev(element)  ((element)->prev)

#endif /* _LIST_H */

2,这是对单链表接口的实现细节:

#include "list.h"

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

void dlist_init(DList *list,void (*destroy)(void *data))
{
	list->size = 0;
	list->destroy = destroy;
	list->head = NULL;
	list->tail = NULL;

	return;
}

void dlist_destroy(DList *list)
{
	void *data;
	while(dlist_size(list) > 0)
	{
		if(dlist_remove(list,dlist_tail(list),(void **)&data) == 0 && list->destroy != NULL)
			list->destroy(data);
	}
	memset(list,0,sizeof(DList));
	return;
}

/* 插入成功返回1,否则返回 -1
 * element == NULL ,链表为空
 */
int dlist_ins_next(DList *list,DListElmt *element,const void *data)
{
	DListElmt *new_element;
	if((new_element = (DListElmt *)malloc(sizeof(DListElmt ))) == NULL)
		return -1;
	new_element->data= (void *)data;

	if(element == NULL && dlist_size(list) != 0)
		return -1;
	
	if(dlist_size(list) == 0)
	{
		list->head = new_element;
		new_element->prev = NULL;
		new_element->next = NULL;
		list->tail = new_element;
	}
	else 
	{
		new_element->next = element->next;
		new_element->prev = element;
		
		if(element->next == NULL)
			list->tail = new_element;
		else
			element->next->prev = new_element;
		element->next = new_element;
	}
	list->size++;
	return 0;
}


/* 插入成功返回0,否则返回-1
 *  若element == NULL,链表应该为空 
 */
int dlist_ins_prev(DList *list,DListElmt *element,const void *data) //成功返回0,失败返回-1
{
	DListElmt *new_element;
	if((new_element = (DListElmt *)malloc(sizeof(DListElmt ))) == NULL)
		return -1;
	new_element->data = (void *)data;

	if(element == NULL && dlist_size(list) != 0)
			return -1;
	if(dlist_size(list) == 0)
	{
		list->head = new_element;
		new_element->prev = NULL;
		new_element->next = NULL;
		list->tail = new_element;
	}
	else
	{
		new_element->next = element;
		new_element->prev = element->prev;

		if(element->prev == NULL)
		{
			list->head = new_element;
		}
		else
		{
			element->prev->next = new_element;
		}
		element->prev = new_element;
	}
	list->size++;
	return 0;
}

/* 删除链表中指定的元素
 */
int dlist_remove(DList  *list,DListElmt *element,void **data)
{
	if(element == NULL || dlist_size(list) == 0)
		return -1;

	*data = element->data;
	if(element == list->head)
	{
		list->head = element->next;
		if(list->head == NULL)
			list->tail = NULL;
		else
			element->next->prev = NULL;
	}
	else
	{
		element->prev->next = element->next;
		if(element->next == NULL)
			list->tail = element->prev;
		else
			element->next->prev = element->prev;
	}
	free(element);
	list->size--;
	return 0;
}

3,栈的接口定义:

#ifndef _STACK_H
#define _STACK_H

#include "list.h"
#include <stdlib.h>

typedef List Stack;

#define stack_init list_init

#define stack_destroy list_destroy

int stack_push(Stack *stack,const void *data);

int stack_pop(Stack *stack,void **data);

#define stack_size list_size

#define stack_peek ((stack)->head == NULL? NULL :(stack)->head = data)

#endif /* _STACK_H */

4,栈的接口的实现:

#include "list.h"
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int stack_push(Stack *stack,const void *data)
{
	return list_ins_next(stack,NULL,data);
}

int stack_pop(Stack *stack,void **data)
{
	return list_rem_next(stack,NULL,data);
}

5,栈的简单操作:

#include <stdio.h>
#include "list.h"
#include "stack.h"
#include <stdlib.h>
#include <string.h>

Stack stack;
void destroy(void *data)
{
	printf("in destroy ...\n");
	return;
}

typedef struct student_
{
	char name[40];
	unsigned char chinese;
	unsigned char math;
}student;

student *stu_init(char *nam,const unsigned char chinese,const unsigned char math)
{
	int i;
	student *ptr = (student *)malloc(sizeof(student));
	if(ptr == NULL)
		return NULL;

	memset(ptr->name,0,sizeof(ptr->name));
	for(i = 0;i < strlen(nam);i++)
		ptr->name[i] = nam[i];
	ptr->name[i] = '\0';

	ptr->chinese = chinese;
	ptr->math = math;

	return ptr;
}

student *dete(student *ptr,int n)
{
	int i;
	ListElmt *elem;

	for(i = 0;i < n;i++)
	{
		elem = list_head(&stack);
		ptr = list_data(elem);
		stack_pop(&stack,(void **)&ptr);
	}
	return ptr;
}

void loop_print(void)
{
	ListElmt *elem;
	student *ptr;
	int i;
	elem = list_head(&stack);
	for(i = 0;i< stack_size(&stack);i++)
	{
		ptr = list_data(elem);
		printf("name=%s chinese=%d math=%d\n",ptr->name,ptr->chinese,ptr->math);
		elem = list_next(elem);
	}	
}

int main(void)
{
	student *ptr = NULL;
	student *ptr1;
	student *ptr2;
	student *ptr3;
	student *ptr4;
	student *ptr5;

	stack_init(&stack,destroy);
	printf("Init ok!\n");

	ptr1 = stu_init("zhm1",61,61);
	ptr2 = stu_init("zhm2",62,62);
	ptr3 = stu_init("zhm3",63,63);
	ptr4 = stu_init("zhm4",64,64);
	ptr5 = stu_init("zhm5",65,65);

	stack_push(&stack,(void *)ptr1);
	stack_push(&stack,(void *)ptr2);
	stack_push(&stack,(void *)ptr3);
	stack_push(&stack,(void *)ptr4);
	stack_push(&stack,(void *)ptr5);

	loop_print();

	//删除第三个元素,对于栈的特性,意味着最后压入的三个元素将都删除
	printf("now :\n");
	dete(ptr,3);
	loop_print();

	//全部弹出,也就是销毁
	stack_destroy(&stack);
	printf("all pop-up,then: %d\n",stack_size(&stack));
	return 0;
}

下面是执行结果:



(OK)





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值