抽象数据类型(Abstract Data Type,ADT)是计算机科学中具有类似行为的特定类别的数据结构的数学模型;或者具有类似语义的一种或多种程序设计语言的数据类型。抽象数据类型是间接定义的,通过其上的可执行的操作以及这些操作的效果的数学约束(与可能的代价)。——维基百科
接口头文件LinkStack.h
:
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
typedef enum Status
{
ERROR = 0,
SUCCESS = 1
} Status;
typedef int ElemType;
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
} StackNode, *LinkStackPtr;
typedef struct LinkStack
{
LinkStackPtr top;
int count;
} LinkStack;
// LinkStack.
Status initLStack(LinkStack *s); // 初始化栈
Status isEmptyLStack(LinkStack *s); // 判断栈是否为空
Status getTopLStack(LinkStack *s,ElemType *e); // 得到栈顶元素
Status clearLStack(LinkStack *s); // 清空栈
Status destroyLStack(LinkStack *s); // 销毁栈
Status LStackLength(LinkStack *s,int *length); // 检测栈长度
Status pushLStack(LinkStack *s,ElemType data); // 入栈
Status popLStack(LinkStack *s,ElemType *data); // 出栈
Status printStack(LinkStack * s); // 实时打印链栈
int InputNumber(); // 输入整数检测
#endif
使用接口main.c
:
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
int main()
{
int flag = 0; // There is no stack.
LinkStack *head = (LinkStack*)malloc(sizeof(StackNode));
head->count = 0;
head->top = NULL;
while(1)
{
system("cls");
printf(" \n");
printf(" \n");
printf("-----------------\n");
printf(">>> 1.Initialize \n");
printf(">>> 2.Push \n");
printf(">>> 3.Pop \n");
printf(">>> 4.Clear \n");
printf(">>> 5.Destroy \n");
printf(">>> 6.Length \n");
printf(">>> 7.isEmpty \n");
printf(">>> 8.getTop \n");
printf(">>> 9.Exit \n");
printf("-----------------\n");
printStack(head);
printf("-----------------\n");
printf("Input a choice you want:");
switch(InputNumber())
{
case 1:
initLStack(head);
flag = 1;
break;
case 2:
if(flag == 1)
{
printf("Input the data to be push:");
pushLStack(head, InputNumber());
}
else
{
printf("Now there is no stack.\n");
}
break;
case 3:
if(flag == 1)
{
ElemType *e = (ElemType*)malloc(sizeof(ElemType));
popLStack(head, e);
}
else
{
printf("Now there is no stack.\n");
}
break;
case 4:
if(flag == 1)
{
clearLStack(head);
}
else
{
printf("Now there is no stack.\n");
}
break;
case 5:
if(flag == 1)
{
destroyLStack(head);
flag = 0;
}
else
{
printf("Now there is no stack.\n");
}
break;
case 6:
{
int *length = (int*)malloc(sizeof(int));
LStackLength(head, length);
}
break;
case 7:
if(flag == 1)
{
isEmptyLStack(head);
}
else
{
printf("Now there is no stack.\n");
}
break;
case 8:
if(flag == 1)
{
ElemType *e = (ElemType*)malloc(sizeof(ElemType));
getTopLStack(head, e);
}
else
{
printf("Now there is no stack.\n");
}
break;
case 9:
printf("\nByeBye~");
exit(0);
break;
default:
printf("No such option.\n");
}
system("pause");
}
return 0;
}
实现接口LinkStack.c
:
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
// LinkStack.
StackNode *bottom = NULL;
// LinkStack.
Status initLStack(LinkStack *s)
{
s->count = 0;
s->top = (StackNode*)malloc(sizeof(StackNode));
s->top->data = 1234567890;
s->top->next = NULL;
bottom = s->top;
printf("Successfully initialize the stack.\n");
return SUCCESS;
}
Status isEmptyLStack(LinkStack *s)
{
if (s->count == 0)
{
printf("It is empty.\n");
return SUCCESS;
}
printf("Not empty.\n");
return ERROR;
}
Status getTopLStack(LinkStack *s, ElemType *e)
{
if(s->top == NULL)
{
printf("There is no stack.\n");
return ERROR;
}
*e = s->top->data;
printf("The top element is %d.\n", *e);
return SUCCESS;
}
Status clearLStack(LinkStack *s)
{
StackNode* p = NULL;
s->count = 0;
s->top = bottom;
p = bottom = bottom->next;
while (p)
{
p = bottom->next;
free(bottom);
bottom = p;
}
printf("Successfully clear the stack.\n");
return SUCCESS;
}
Status destroyLStack(LinkStack *s)
{
StackNode* p = NULL;
s->count = 0;
s->top = NULL;
while (p)
{
p = bottom->next;
free(bottom);
bottom = p;
}
printf("Successfully destroy the stack.\n");
return SUCCESS;
}
Status LStackLength(LinkStack *s, int *length)
{
if(s->top == NULL)
{
printf("There is no stack.\n");
return ERROR;
}
*length = s->count;
printf("The length of the stack is %d.\n", *length);
return SUCCESS;
}
Status pushLStack(LinkStack *s, ElemType data)
{
StackNode * p = (StackNode*)malloc(sizeof(StackNode));
p->data = data;
p->next = NULL;
s->top->next = p;
s->top = p;
s->count++;
printf("Successfully push %d to the stack.\n", data);
return SUCCESS;
}
Status popLStack(LinkStack *s, ElemType *data)
{
StackNode * p = bottom;
if (s->count == 0)
{
printf("The stack is empty.\n");
return ERROR;
}
else
{
*data = s->top->data;
for (; p; p = p->next) {
if (p->next == s->top) {
free(p->next);
p->next = NULL;
s->top = p;
s->count--;
break;
}
}
printf("Successfully pop %d out the stack.\n", *data);
return SUCCESS;
}
}
// 实时打印链栈
Status printStack(LinkStack * s)
{
StackNode * p = NULL;
if (s->top == NULL) {
printf("There is no stack now.\n");
return ERROR;
}
else if (s->count == 0)
{
return ERROR;
}
for (p = bottom->next; p; p = p->next)
{
printf("|%d", p->data);
}
printf("\n");
return SUCCESS;
}
// 输入整数检测
int InputNumber()
{
int num = 0; // Store converted numbers.
int status = 0; // Flag status.
char str[100]; // Receive string.
do
{
scanf("%s", str);
status = SUCCESS;
for (int i = 0; str[i] != '\0'; i++)
{
// Check for illegal characters.
if (i == 0)
{
if (str[i] == '-' || str[i] == '+')
continue;
}
else
{
if (str[i] < '0' || str[i] > '9')
{
status = ERROR;
}
}
}
if (status == ERROR) {
printf("Illegally input, please input again:");
}
else
{
int i = 0;
// Convert string to number.
for (i = 0, num = 0; str[i] != '\0'; i++)
{
if (i == 0)
{
if (str[i] == '-' || str[i] == '+')
{
continue;
}
else
{
num *= 10;
num += (str[i] - 48);
}
}
else
{
num *= 10;
num += (str[i] - 48);
}
}
if (str[0] == '-')
{
num = -num;
}
// Check if the number entered is out of bounds.
if (i >= 10)
{
printf("Overflow, please input again:");
status = ERROR;
}
}
} while (status == ERROR);
return num;
}