数据结构第二站:栈_链栈

一.定义

栈是一种限定仅在表尾进行插入和删除操作的线性表

二.存储结构

(一)顺序存储

数据结构第二站:栈_链栈_02

解释:顺序栈会受到空间容量的限制,所以我们使用链栈

(二)链式存储

数据结构第二站:栈_链栈_03

解释:链栈很好的解决了容量问题

三.基本操作代码

基本操作:入栈、出栈、取栈顶

(一)顺序栈基本操作

/* 栈为一种先进后出的数据类型,仅可以在栈顶进行操作 */


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100
typedef struct
{
int *base;
int *top;
int stacksize;
}SqStack;
//函数声明
void InitStack(SqStack *S); //初始化顺序栈
void Push(SqStack *S,int key); //元素入栈
void Pop(SqStack *S,int key); //元素出栈
void Gettop(SqStack *S); //取栈顶元素

int main()
{
int total,key,i;
SqStack *S;
InitStack(S);
printf("请输入元素总个数:\n");
scanf("%d",&total);
printf("请输入元素:\n");
for(i=0;i<total;i++){
scanf("%d",&key); //获取元素
Push(S,key); //压入栈中
}
if(i==total){
printf("入栈成功!\n");
}
printf("出栈结果为:\n");
while(S->top!=S->base)
{
Pop(S,key);
}
return 0;
}
//初始化顺序栈
void InitStack(SqStack *S){
S->base = (int *)malloc(sizeof(int)*MAXSIZE);// 为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
if(!S->base)
printf("动态分配内存空间失败!\n");
else{
S->top=S->base; //top初始为base,空栈
S->stacksize =MAXSIZE;
printf("初始化成功\n");}
}

//元素入栈
void Push(SqStack *S,int key){
//插入元素key为新的栈顶元素
if(S->top-S->base==S->stacksize)
printf("栈已经满!");
else{
*S->top++=key;
}
}

//元素出栈
void Pop(SqStack *S,int key){
if(S->top==S->base)
printf("栈空!\n");
else{
key=*--S->top; //栈顶指针减1,将栈顶元素赋给key
printf("出栈成功,出栈元素为%d\n",key);
}
}

//取栈顶元素
void Gettop(SqStack *S){
//返回S的栈顶元素,不修改栈顶指针
if(S->top!=S->base)
{
printf("%d\t",*(S->top-1)); //返回栈顶元素的值
}
}

(二)链栈基本操作

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _Student//学生基本信息
{
char ID[15];//学号
char name[10];//姓名
float math;//数学成绩
float chinese;//语文成绩
float english;//英语成绩
float average;//平均成绩
}Student;//别名
typedef struct StackNode{
Student data;
struct StackNode*next;
}StackNode,*LinkStack;
StackNode*S=NULL;
void Inputinformation(LinkStack &S);//输入学生信息
float Average(StackNode* pnewstudent);//求学生成绩的平均数
void Judge(LinkStack &S); //判断栈是否为空
void Clear(LinkStack &S); //清空栈
void OutputInformation(LinkStack &S);//输出栈中全部元素
void Output(LinkStack &S); //输出栈顶元素
void Number(LinkStack &S);//统计栈中元素总数
void Welcome()//操作提示信息
{
printf("****************************************************************\n");
printf("********* 栈的链式的基本操作 ************\n");
printf("****************************************************************\n");
printf("* 请选择功能列表 *\n");
printf("* 1.输入信息(入栈) *\n");
printf("* 2.判断栈是否为空 *\n");
printf("* 3.栈的清空 *\n");
printf("* 4.输出学生信息 *\n");
printf("* 5.输出全部学生信息 *\n");
printf("* 6.统计学生人数 *\n");
printf("* 7.返回选择菜单 *\n");
printf("* 0.退出系统 *\n");
printf("****************************************************************\n");
}
int main()
{
int choice;
Welcome();
while(1){
printf("请输入操作序号:");
scanf("%d",&choice);
switch(choice)
{
case 1: Inputinformation(S); break;
case 2: Judge(S);break;
case 3: Clear(S); break;
case 4: Output(S);break;
case 5:OutputInformation(S);break;
case 6:Number(S);break;
case 7:Welcome();break;
case 0: exit(0);break;
default: printf("输入有误,请重新输入:\n");break;
}
}
return 0;
}
float Average(StackNode* pnewstudent)//求平均数
{
return((pnewstudent->data.math+pnewstudent->data.chinese+pnewstudent->data.english)/3.0);
}

void Inputinformation(LinkStack &S)//输入元素
{

StackNode*p=new StackNode;
if (S == NULL)
S = p;
else
{
p->next = S;
S= p;
}
printf("请输入学生学号:\n");
scanf("%s",p->data.ID);
printf("请输入学生姓名:\n");
scanf("%s",p->data.name);
printf("请输入数学成绩:\n");
scanf("%f",&p->data.math);
printf("请输入语文成绩:\n");
scanf("%f",&p->data.chinese);
printf("请输入英语成绩:\n");
scanf("%f",&p->data.english);
p->data.average=Average(p);
printf("录入学生信息成功:\n");
system("pause");//暂停
//system("cls");//清屏
}
void Judge(LinkStack &S){
if(S==NULL){
printf("栈已空!\n");
}
else{
printf("栈未空!\n");
}
}
void Clear(LinkStack &S)
{
while(S!=NULL)
{StackNode *p;
p=S;
S=S->next;
delete p;
}
if(S==NULL){
printf("栈已经清空!\n");
}
}
void OutputInformation(LinkStack &S){
StackNode *p;
printf("*************************************************************\n");
printf("* 欢迎使用学生成绩管理系统 *\n");
printf("*************************************************************\n");
printf("* 学号\t姓名\t数学成绩\t语文成绩\t英语成绩\t 平均成绩 *");
printf("\n");
while(S!=NULL){
p=S;
printf("%s\t%s\t %.2f\t %.2f\t %.2f\t %.2f\n", p->data.ID,
p->data.name,
p->data.math,
p->data.chinese,
p->data.english,
p->data.average
);
printf("**********************************************\n");
S=S->next;
}
}
void Output(LinkStack &S)

{
StackNode *p;
if(S!=NULL){
printf("*************************************************************\n");
printf("* 欢迎使用学生成绩管理系统 *\n");
printf("*************************************************************\n");
printf("* 学号\t姓名\t数学成绩\t语文成绩\t英语成绩\t 平均成绩 *");
printf("\n");
p=S;
printf("%s\t%s\t %.2f\t %.2f\t %.2f\t %.2f\n", p->data.ID,
p->data.name,
p->data.math,
p->data.chinese,
p->data.english,
p->data.average
);
printf("**********************************************\n");
S=S->next;

}
else{
printf("栈已空,已经无元素!\n");
}
}
void Number(LinkStack &S){
int i=0;
while(S!=NULL){
++i;
S=S->next;
}
printf("学生总人数为:");
printf("%d\n",i);
}

阶层递归

/*递归实现全排列*/

#include<stdio.h>

//交换函数值
void swap(int arr[],int m,int n)
{
int temp=arr[m];
arr[m]=arr[n];
arr[n]=temp;
}
//全排列
void All_permutation(int arr[],int p,int q)
{
if(p==q) //递归出口
{
for( int i=0;i<=q;i++)
printf(" %d ",arr[i]);
putchar('\n');
}
else
{
for(int i=p;i<=q;i++) //将每个数据依次放在第一个位置
{
swap(arr,p,i);
All_permutation(arr,p+1,q); //剩下的n-1个数进行全排列
swap(arr,p,i); //将下一个数放在第一位之前应让之前调换的数据归位
}

}
}
int main()
{
int i;
int *arr;
int N;
printf("请输入你要全排列的数据个数:\n");
scanf("%d",&N);
for(i =0;i<N;i++)
arr[i]=i+1;
printf("全排列结果为:\n");
All_permutation(arr,0,N-1);
return 0;
}