您的位置:首页 > 理论基础 > 数据结构算法

数据结构之栈

2015-11-30 22:24 435 查看
决定采用何种方式来存储数据是非常重要的,这样便于检索数据时,数据会自动按照某种规定的顺序给出。

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

栈:先进后出。

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

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

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

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);
pri
9bad
ntf("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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: