栈是限定仅在表尾进行插入和删除操作的线性表。表尾端称为栈顶,表头端称为栈尾;栈又称为“先进后出”的线性表
1.栈的顺序存储
//头文件SeqList.h
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#ifndef _MY_SEQLIST_H_
#define _MY_SEQLIST_H_
typedef void SeqList;
typedef void SeqListNode;
//创建并且返回一个空的线性表
SeqList* Seqlist_Create(int capacity);
//销毁一个线性表
void SeqList_Destroy(SeqList* list);
//将一个线性表list中的所有元素清空, 线性表回到创建时的初始状态
void SeqList_Clear(SeqList* list);
//返回一个线性表list中的所有元素个数
int SeqList_Length(SeqList* list);
//返回一个线性表list中的容量
int SeqList_capacity(SeqList* list);
//向一个线性表list的pos位置处插入新元素node
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
//获取一个线性表list的pos位置处的元素
SeqListNode* Seqlist_Get(SeqList* list, int pos);
//删除一个线性表list的pos位置处的元素返回值为被删除的元素,NULL表示删除失败
SeqListNode* Seqlist_Delete(SeqList* list, int pos);
#endif
//头文件SeqStack.h
#ifndef _MY_SEQSTACK_H_
#define _MY_SEQSTACK_H_
typedef void SeqStack;
SeqStack* SeqStack_Create(int capacity);
void SeqStack_Destroy(SeqStack* stack);
void SeqStack_Clear(SeqStack* stack);
int SeqStack_Push(SeqStack* stack, void* item);
void* SeqStack_Pop(SeqStack* stack);
void* SeqStack_Top(SeqStack* stack);
int SeqStack_Capacity(SeqStack* stack);
int SeqStack_Size(SeqStack* stack);
#endif
//函数实现
//seqlist.c
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#include"Seqlist.h"
typedef struct _tag_Seqlist
{
int length;//长度
int capacity;//容量
unsigned int* node;//数组
}TSeqlist;
//创建并且返回一个空的线性表
SeqList* Seqlist_Create(int capacity)
{ //创建线性表
int ret = 0;
TSeqlist *tmp=NULL;
tmp = (TSeqlist *)malloc(sizeof(TSeqlist));
if (tmp==NULL)
{
ret = -1;
printf("func:Seqlist_Create err%d\n",ret);
return NULL;
}
memset(tmp, 0, sizeof(TSeqlist));
//根据capacity大小分配结点的空间
tmp->node = (unsigned int *)malloc(sizeof(unsigned int *) * capacity);
if (tmp->node == NULL)
{
ret = -2;
printf("func:Seqlist_Create err:malloc err %d\n", ret);
return NULL;
}
tmp->capacity = capacity;
tmp->length = 0;
return tmp;
}
//销毁一个线性表
void SeqList_Destroy(SeqList* list)
{
TSeqlist *tlist=NULL;
if (list == NULL)
{
return ;
}
tlist = (TSeqlist *)list;//强制转换
if (tlist->node!=NULL)
{
free(tlist->node);
}
free(tlist);
return ;
}
//将一个线性表list中的所有元素清空, 线性表回到创建时的初始状态
void SeqList_Clear(SeqList* list)
{
TSeqlist *tlist = NULL;
if (list == NULL)
{
return ;
}
tlist = (TSeqlist *)list;
tlist->length = 0;
return;
}
//返回一个线性表list中的所有元素个数
int SeqList_Length(SeqList* list)
{
TSeqlist *tlist = NULL;
if (list == NULL)
{
return -1;
}
tlist = (TSeqlist *)list;
return tlist->length;
}
//返回一个线性表list中的容量
int SeqList_capacity(SeqList* list)
{
TSeqlist *tlist = NULL;
if (list == NULL)
{
return -1;
}
tlist = (TSeqlist *)list;
return tlist->capacity;
return 0;
}
//向一个线性表list的pos位置处插入新元素node
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
int i = 0, ret = 0;
TSeqlist *tlist = NULL;
if (list == NULL || node==NULL || pos<0)
{
ret = -1;
printf("SeqList_Insert err%d\n",ret);
return ret;
}
tlist = (TSeqlist *)list;
//判断是不是满了
if (tlist->length>=tlist->capacity)
{
ret = -2;
printf("Func:SeqList_Insert err :tlist->length>=tlist->capacity err %d\n", ret);
return ret;
}
//容错修正
if (pos >= tlist->length)
{
pos = tlist->length;
}
//元素后移
for ( i = tlist->length; i > pos; i--)
{
tlist->node[i] = tlist->node[i - 1];
}
//元素插入
tlist->node[pos] = (unsigned int)node;
tlist->length++;
return 0;
}
//获取一个线性表list的pos位置处的元素
SeqListNode* Seqlist_Get(SeqList* list, int pos)
{
int i = 0;
SeqListNode *ret = 0;
TSeqlist *tlist = NULL;
if (list == NULL || pos<0)
{
printf("Func:Seqlist_Get err%d\n", ret);
return ret;
}
tlist = (TSeqlist *)list;
ret = tlist->node[pos];
return ret ;
}
//删除一个线性表list的pos位置处的元素返回值为被删除的元素,NULL表示删除失败
SeqListNode* Seqlist_Delete(SeqList* list, int pos)
{
int i = 0;
SeqListNode *ret = 0;
TSeqlist *tlist = NULL;
//检查
if (list == NULL || pos<0)
{
printf("SeqList_Insert err%d\n", ret);
return ret;
}
tlist = (TSeqlist *)list;
//缓存pos位置
ret = (SeqListNode *)tlist->node[pos];
//元素前移
for (i = pos + 1; i < tlist->length; i++)
{
tlist->node[i-1] = tlist->node[i];
}
tlist->length--;
return ret;
}
//seqstack.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"SeqStack.h"
#include"Seqlist.h"
//创建栈 相当于 创建线性表
SeqStack* SeqStack_Create(int capacity)
{
return Seqlist_Create(capacity);
}
//删除栈 相当于 删除线性表
void SeqStack_Destroy(SeqStack* stack)
{
SeqList_Destroy(stack);
}
//清空栈 相当于 清空线性表
void SeqStack_Clear(SeqStack* stack)
{
SeqList_Clear(stack);
}
//压栈 相当于 在线性表尾部 插入元素
int SeqStack_Push(SeqStack* stack, void* item)
{
return SeqList_Insert(stack,item,SeqList_Length(stack));
}
//出栈 相当于 在线性表尾部 删除元素
void* SeqStack_Pop(SeqStack* stack)
{
return Seqlist_Delete(stack,SeqList_Length(stack)-1);
}
//获取栈的头部元素 相当于 获取线性表的尾部元素
void* SeqStack_Top(SeqStack* stack)
{
return Seqlist_Get(stack, SeqList_Length(stack) - 1);
}
//获取栈的容量 相当于 获取线性表容量
int SeqStack_Capacity(SeqStack* stack)
{
return SeqList_capacity(stack);
}
//获取栈的大小 相当于 获取线性表长度
int SeqStack_Size(SeqStack* stack)
{
return SeqList_Length(stack);
}
//栈的顺序存储结构测试
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"SeqStack.h"
int main()
{
SeqStack *s1 = NULL;
s1=SeqStack_Create(10);
int i = 0;
int a[10];
for (i = 0; i < 5; i++)
{
a[i] = i;
SeqStack_Push(s1, &a[i]);
}
printf("capacity:%d\n",SeqStack_Capacity(s1));
printf("length:%d\n", SeqStack_Size(s1));
printf("top:%d\n", *((int *)SeqStack_Top(s1)));
while (SeqStack_Size(s1)>0)
{
int tmp = *(int *)SeqStack_Pop(s1);
printf("tmp:%d",tmp);
}
system("pause");
return 0;
}
2.栈的链式存储
//头文件linklist.h
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#ifndef _MY_LINKLIST_H_
#define _MY_LINKLIST_H_
typedef void LinkList;
//typedef void LinkListNode;
typedef struct _tag_LinkListNode
{
struct _tag_LinkListNode* next;
}LinkListNode;
//创建并且返回一个空的线性表
LinkList* LinkList_Create();
//销毁一个线性表
void LinkList_Destroy(LinkList* list);
//将一个线性表list中的所有元素清空, 线性表回到创建时的初始状态
void LinkList_Clear(LinkList* list);
//返回一个线性表list中的所有元素个数
int LinkList_Length(LinkList* list);
//向一个线性表list的pos位置处插入新元素node
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);
//获取一个线性表list的pos位置处的元素
LinkListNode* LinkList_Get(LinkList* list, int pos);
//删除一个线性表list的pos位置处的元素返回值为被删除的元素,NULL表示删除失败
LinkListNode* LinkList_Delete(LinkList* list, int pos);
#endif
//头文件linkstack.h
#ifndef _MY_LINKSTACK_H_
#define _MY_LINKSTACK_H_
typedef void LinkStack;
LinkStack* LinkStack_Create();
void LinkStack_Destroy(LinkStack* stack);
void LinkStack_Clear(LinkStack* stack);
int LinkStack_Push(LinkStack* stack,void* item);
void* LinkStack_Pop(LinkStack* stack);
void* LinkStack_Top(LinkStack* stack);
int LinkStack_Size(LinkStack* stack);
int LinkStack_Capacity(LinkStack* stack);
#endif
//函数实现
//linklist.c
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#include"LinkList.h"
typedef struct LinkList
{
LinkListNode header;
int length;
}TLinkList;
//创建并且返回一个空的线性表
LinkList* LinkList_Create()
{
TLinkList *tmp = NULL;
tmp = (TLinkList*)malloc(sizeof(TLinkList));
memset(tmp, 0, sizeof(TLinkList));
tmp->length = 0;
tmp->header.next = NULL;
return tmp;
}
//销毁一个线性表
void LinkList_Destroy(LinkList* list)
{
if (list != NULL)
{
free(list);
list = NULL;
}
return ;
}
//将一个线性表list中的所有元素清空, 线性表回到创建时的初始状态
void LinkList_Clear(LinkList* list)
{
TLinkList *tlist = NULL;
if (list == NULL)
{
return;
}
tlist = (TLinkList *)list;
tlist->length = 0;
tlist->header.next = NULL;
return ;
}
//返回一个线性表list中的所有元素个数
int LinkList_Length(LinkList* list)
{
TLinkList *tlist = NULL;
if (list == NULL)
{
return;
}
tlist = (TLinkList *)list;
return tlist->length;
}
//向一个线性表list的pos位置处插入新元素node
//指针指向谁就把谁的地址给指针
//分清 链表的操作逻辑和 辅助指针变量之间的关系
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
int i = 0, ret = 0;
LinkListNode* current=NULL;
TLinkList *tlist = NULL;
if (list == NULL||node==NULL||pos<0)
{
ret = -1;
printf("Func:LinkList_Insert err%d\t",ret);
return ;
}
tlist = (TLinkList *)list;
current = &(tlist->header);
for (i = 0; i < pos ; i++)
{
current = current->next;
}
//将node的next指向下一个元素的首地址
node->next=current->next;
//将上一个元素的next指向node的首地址
current->next=node;
tlist->length++;
return 0;
}
//获取一个线性表list的pos位置处的元素
LinkListNode* LinkList_Get(LinkList* list, int pos)
{
int i = 0, ret = 0;
LinkListNode* current = NULL;
TLinkList *tlist = NULL;
if (list == NULL || pos<0)
{
ret = 0;
printf("Func:LinkList_Insert err%d\t", ret);
return NULL;
}
tlist = (TLinkList *)list;
current = &(tlist->header);
for (i = 0; i < pos && (current->next != NULL); i++)
{
current = current->next;
}
return current->next;
}
//删除一个线性表list的pos位置处的元素返回值为被删除的元素,NULL表示删除失败
LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
int i = 0, ret = 0;
LinkListNode* current = NULL;
LinkListNode* tmp = NULL;
TLinkList *tlist = NULL;
if (list == NULL || pos<0)
{
ret = -1;
printf("Func:LinkList_Insert err%d\t", ret);
return;
}
tlist = (TLinkList *)list;
current = &(tlist->header);
for (i = 0; i < pos && (current->next != NULL); i++)
{
current = current->next;
}
//将删除元素nodede首地址找出来
tmp = current->next;
//将删除元素node的下一个元素的首地址赋给上一个元素的next
current->next = tmp->next;
tlist->length--;
return tmp;//返回删除元素的地址
}
//linkstack.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkStack.h"
#include"LinkList.h"
typedef struct _tag_LinkStackNode
{
LinkListNode node;
void* item;
}TLinkStackNode;
//创建栈
LinkStack* LinkStack_Create()
{
return LinkList_Create();
}
//销毁栈
void LinkStack_Destroy(LinkStack* stack)
{
LinkStack_Clear(stack);
LinkList_Destroy(stack);
}
//清空栈
//清空栈 涉及到 栈元素生命周期的管理
//所有的栈元素都是malloc,把栈元素弹出,并释放内存
void LinkStack_Clear(LinkStack* stack)
{
if (stack == NULL)
{
return;
}
while (LinkStack_Size(stack) > 0)
{
LinkStack_Pop(stack);//pop中释放内存
}
}
//压栈,链表头部插入元素
//void* item--->>链表结点
int LinkStack_Push(LinkStack* stack, void* item)
{
TLinkStackNode *tmp = NULL;
int ret = 0;
tmp = (TLinkStackNode *)malloc(sizeof(TLinkStackNode));
if (tmp == NULL)
{
return -1;
}
memset(tmp, 0, sizeof(TLinkStackNode));
tmp->item = item;
ret=LinkList_Insert(stack, (LinkListNode*)tmp, 0);
if (ret != 0)
{
printf("func:LinkList_Insert err:%d",ret);
if (tmp != NULL)
{
free(tmp);
}
return ret;
}
return ret;
}
//出栈,删除链表头结点
//链表结点---->>栈的结点
void* LinkStack_Pop(LinkStack* stack)
{
void* item = NULL;//栈的业务结点
TLinkStackNode *tmp = NULL;
tmp = (TLinkStackNode *)LinkList_Delete(stack, 0);
if (tmp == NULL)
{
return NULL;
}
item = tmp->item;
//insert中分配了内存,需要释放
free(tmp);
return item;
}
//获取栈顶元素
//获取线性表的0号位置
void* LinkStack_Top(LinkStack* stack)
{
TLinkStackNode *tmp = NULL;
tmp = (TLinkStackNode *)LinkList_Get(stack,0);
if (tmp == NULL)
{
return NULL;
}
return tmp->item;
}
//获取栈的大小
int LinkStack_Size(LinkStack* stack)
{
return LinkList_Length(stack);
}
//栈的链式存储测试
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkStack.h"
int main()
{
LinkStack *s1 = NULL;
s1 = LinkStack_Create();
int i = 0;
int a[10];
for (i = 0; i < 5; i++)
{
a[i] = i;
LinkStack_Push(s1, &a[i]);
}
printf("length:%d\n", LinkStack_Size(s1));
printf("top:%d\n", *((int *)LinkStack_Top(s1)));
while (LinkStack_Size(s1)>0)
{
int tmp = *(int *)LinkStack_Pop(s1);
printf("tmp:%d", tmp);
}
system("pause");
return 0;
}