数据结构—P4 栈
简介
栈
栈(stack)是限定仅在表尾进行插入和删除操作的线性表
允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈;栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
栈的插入操作,叫作进栈、入栈
栈的删除操作,叫作出栈,也有的叫作弹栈
顺序栈
既然栈时线性表的特例,那么栈的顺序存储其实也是线性表顺序存储的简化,简称顺序栈
链式栈
栈的链式存储结构,简称为链式栈
顺序栈的实现
创建结构体
创建所需文件
编写Makfile
test:test.o sqstack.o
gcc -o test test.o sqstack.o
test.o:test.c sqstack.h
gcc -c test.c
sqstack.o:sqstack.c sqstack.h
gcc -c sqstack.c
.PHONY:clean
clean:
rm *.o
编写sqstack.h
//定义int类型的数据的别名为data_t
typedef int data_t;
//定义顺序栈结构体,并创建结构体的别名为sqstack
typedef struct{
data_t *data;//数据指针
int maxlen;//数据长度
int top;//栈顶位置
}sqstack;
创建与销毁
编写sqstack.h
编写创建函数
sqstack* sqstack_create(int len){
sqstack *s;
//分配内存空间
if((s = (sqstack *)malloc(sizeof(sqstack))) == NULL){
printf("malloc is failed\n");
return NULL;
}
if((s->data = (data_t *)malloc(len * sizeof(data_t))) == NULL){
printf("malloc is failed\n");
free(s);
return NULL;
}
//表数据初始化
memset(s->data,0,len*sizeof(data_t));
s->maxlen = len;
s->top = -1;
//返回表
return s;
}//创建表
编写销毁函数
int sqstack_free(sqstack *s){
if(s == NULL){
printf("s is NULL");
return -1;
}
if(s->data != NULL){
free(s->data);
}
free(s);
}//释放表
编写清空函数
int sqstack_clear(sqstack *s){
if(s == NULL){
printf("s is NULL\n");
return -1;
}
//将栈顶指向-1清空栈
s->top = -1;
return 0;
}//清空表
状态属性
编写sqstack.h
创建是否为空函数
int sqstack_isempty(sqstack *s){
if(s == NULL){
printf("s is NULL\n");
return -1;
}
//判断是否为空
if(s->top == -1){
return 1;
}else{
return 0;
}
}//表是否为空
创建是否为满函数
int sqstack_isfull(sqstack *s){
if(s = NULL){
printf("s is NULL\n");
return -1;
}
//判断是否为满
if(s->top == s->maxlen-1){
return 1;
}else{
return 0;
}
}//表是否为满
创建栈顶判断函数
data_t sqtack_top(sqstack *s){
return (s->data[s->top]);
}//栈顶判断
入栈出栈
编写sqstack.h
编写入栈程序
int sqstack_push(sqstack *s,data_t value){
if(s == NULL){
printf("s is NULL");
return -1;
}
if(s->top == s->maxlen-1){
printf("stack is full\n");
}
s->top++;
s->data[s->top] = value;
return 0;
}//表入栈
编写出栈程序
data_t sqstack_pop(sqstack *s){
s->top--;
return (s->data[s->top+1]);
}//表出栈
查询操作
编写sqstack.h
编写查询全部信息
int sqstack_show(sqstack *s){
int i;
if(s == NULL){
printf("s is NULL");
return -1;
}
if(sqstack_isempty(s)){
printf("sqstack is empty\n");
}
printf("sqstack:\n");
for(i = 0;i <= s->top;i++){
printf("%d ",s->data[i]);
}
printf("\n");
return 0;
}//查询并显示所有表内容
编写test.c
//入栈出栈测试程序
int pushpop_test(){
sqstack *s;
int value;
s = sqstack_create(100);
if(s == NULL){
return -1;
}
while(1){
printf("input(-1quit):");
scanf("%d",&value);
if(value == -1){
break;
}else{
sqstack_push(s,value);
sqstack_show(s);
}
}
while(!sqstack_isempty(s)){
sqstack_pop(s);
sqstack_show(s);
}
sqstack_free(s);
}
测试程序
编写查询指定位置内容
int sqstack_poslocate(sqstack *s,int pos){
if(s == NULL){
printf("s is NULL");
return -1;
}
if(sqstack_isempty(s)){
printf("sqstack is empty\n");
}
printf("sqstack:\n%d\n",s->data[pos]);
return 0;
}//查询指定位置内容
编写查询指定内容位置
int sqstack_valuelocate(sqstack *s,data_t value){
int i;
if(s == NULL){
printf("s is NULL");
return -1;
}
if(sqstack_isempty(s)){
printf("sqstack is empty\n");
}
for(i = 0;i <= s->top;i++){
if(s->data[i] == value){
printf("pos:\n%d\n",i);
}
}
}//查询指定内容位置
编写test.c
//查询测试程序
int locate_test(){
sqstack *s;
int input,pos,value;
s = sqstack_create(100);
if(s == NULL){
return -1;
}
while(1){
printf("input(-1quit):");
scanf("%d",&input);
if(input == -1){
break;
}else{
sqstack_push(s,input);
sqstack_show(s);
}
}
while(1){
printf("pos(-1quit):");
scanf("%d",&pos);
if(pos == -1){
break;
}else{
sqstack_poslocate(s,pos);
}
}
while(1){
printf("value(-1quit):");
scanf("%d",&value);
if(value == -1){
break;
}else{
sqstack_valuelocate(s,value);
}
}
sqstack_free(s);
}
测试程序
修改操作
编写sqstack.h
编写修改指定位置内容
int sqstack_posmodify(sqstack *s,int pos,data_t value){
if(s == NULL){
printf("s is NULL");
return -1;
}
if(sqstack_isempty(s)){
printf("sqstack is empty\n");
}
s->data[pos] = value;
return 0;
}//修改指定位置内容
编写修改指定内容为指定内容
int sqstack_valuemodify(sqstack *s,data_t rvalue,data_t value){
int i;
if(s == NULL){
printf("s is NULL");
return -1;
}
if(sqstack_isempty(s)){
printf("sqstack is empty\n");
}
for(i = 0;i <= s->top;i++){
if(s->data[i] == rvalue){
s->data[i] = value;
}
}
return 0;
}//修改指定内容到指定内容
编写test.c
//修改测试程序
int modify_test(){
sqstack *s;
int input,pos,rvalue,value;
s = sqstack_create(100);
if(s == NULL){
return -1;
}
while(1){
printf("input(-1quit):");
scanf("%d",&input);
if(input == -1){
break;
}else{
sqstack_push(s,input);
sqstack_show(s);
}
}
while(1){
printf("pos(-1quit):");
scanf("%d",&pos);
if(pos == -1){
break;
}
printf("value:");
scanf("%d",&value);
sqstack_posmodify(s,pos,value);
sqstack_show(s);
}
while(1){
printf("rvalue(-1quit):");
scanf("%d",&rvalue);
if(rvalue == -1){
break;
}
printf("value:");
scanf("%d",&value);
sqstack_valuemodify(s,rvalue,value);
sqstack_show(s);
}
}
测试程序
链式栈的实现
创建结构体
创建文件
编写Makefile
test:test.o lkstack.o
gcc -o test test.o lkstack.o
test.o:test.c lkstack.h
gcc -c test.c
lkstack.o:lkstack.c lkstack.h
gcc -c lkstack.c
.PHONY:clean
clean:
rm *.o
编写sqstack.h
//定义int类型的数据的别名为data_t
typedef int data_t;
//定义链式栈机构体,并创建别名为listnode和lkstack
typedef struct node{
data_t data;
struct node *next;
}listnode,*lkstack;
创建与销毁
编写sqstack.h
编写创建函数
lkstack lkstack_create(){
lkstack s;
if((s = (lkstack)malloc(sizeof(listnode))) == NULL){
printf("malloc is failed\n");
return NULL;
}
s->data = 0;
s->next = NULL;
return s;
}//创建表
编写销毁函数
lkstack lkstack_free(lkstack s){
lkstack p;
if(s = NULL){
printf("s is NUll\n");
return NULL;
}
while(s != NULL){
p = s;
s = s->next;
free(p);
}
return NULL;
}//释放表
状态属性
编写sqstack.h
编写是否为空函数
int lkstack_isempty(lkstack s){
if(s == NULL){
printf("s is NULL\n");
return -1;
}
if(s->next == NULL){
return 1;
}else{
return 0;
}
}//表是否为空
编写栈顶函数
int lkstack_top(lkstack s){
lkstack p;
int num = 0;
p = s;
while(p->next != NULL){
num++;
p = p->next;
}
return num;
}//栈顶判断
入栈出栈
编写sqstack.h
编写表入栈函数
int lkstack_push(lkstack s,data_t value){
lkstack p;
if(s == NULL){
printf("s is NULL");
return -1;
}
if((p = (lkstack)malloc(sizeof(listnode))) == NULL){
printf("malloc is failed\n");
return -1;
}
p->data = value;
p->next = s->next;
s->next = p;
return 0;
}//表入栈
编写表出栈函数
data_t lkstack_pop(lkstack s){
lkstack p;
data_t t;
p = s->next;
s->next = p->next;
t = p->data;
free(p);
p = NULL;
return t;
}//表出栈
查询操作
编写sqstack.h
编写显示所有内容
int lkstack_show(lkstack s){
lkstack p;
if(s == NULL){
printf("s is NULL");
return -1;
}
if(lkstack_isempty(s)){
printf("lkstack is empty\n");
}
p = s;
printf("lkstack:\n");
while(p->next != NULL){
printf("%d ",p->next->data);
p = p->next;
}
printf("\n");
}//查询并显示所有表内容
编写test.c
#include <stdio.h>
#include "lkstack.h"
int pushpop_test(){
lkstack s;
int value;
s = lkstack_create();
if(s == NULL){
return -1;
}
while(1){
printf("input(-1quit):");
scanf("%d",&value);
if(value == -1){
break;
}else{
lkstack_push(s,value);
lkstack_show(s);
}
}
while(!lkstack_isempty(s)){
lkstack_pop(s);
lkstack_show(s);
}
}
int main(int argc, const char *argv[])
{
pushpop_test();
return 0;
}
测试程序