目录
一、思维导图
作业:双向循环链表的逆置
/*
* function: 双向循环链表的逆置
* @param [ in]
* @param [out]
* @return
*/
DouleLink rev(DouleLink L)
{
DouleLink rear=L->prev;
DouleLink begin=L;
datatype t="";
while(begin!=rear)
{
strcpy(t,begin->data);
strcpy(begin->data,rear->data);
strcpy(rear->data,t);
begin=begin->next;
rear=rear->prev;
}
return L;
}
二、栈
2.1 栈的介绍
1> 栈:在表尾进行插入和删除的操作受限的线性表。
2> 逻辑结构:线性结构【一对一的关系】
3> 存储结构:顺序存储【顺序栈】、链式存储【链栈】
4> 栈的特点:先进后出【first in last out FILO表】
后进先出【last in first out LIFO表】
5> 栈的入栈和出栈
2.2 顺序栈
认识栈满、栈空、插入、删除、遍历
2.2.1 栈的结构体定义
typedef int datatype;
typedef struct
{
//栈顶
int top;
//数据元素
datatype data[MAXSIZE];
}StackList;
2.2.2 栈的创建
/*
* function: 创建栈
* @param [ in]
* @param [out]
* @return
*/
StackList *create_stack()
{
StackList *stack=(StackList *)malloc(sizeof(StackList));
if(NULL == stack)
{
return NULL;
}
//栈顶置空
stack->top=-1;
memset(stack->data,0,sizeof(stack->data));
return stack;
}
2.2.2 栈的插入【入栈】
/*
* function: 入栈
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int list_stack_push(datatype e,StackList *stack)
{
//1.判断栈是否创建
//2.判断栈是否为满
if(NULL==stack || stack->top==MAXSIZE-1)
{
puts("push stack error");
return -1;
}
//3.入栈:先加后压
//stack->top++;
stack->data[++stack->top]=e;
return 0;
}
2.2.3 栈的删除【出栈】
/*
* function: 出栈
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int list_stack_pop(StackList *stack)
{
//1,判断栈是否创建
//2,判断栈是否为空
if(NULL==stack || stack->top==-1)
{
puts("pop error");
return -1;
}
//3,出栈:先弹后减
printf("pop data is:%d\n",stack->data[stack->top--]);
// stack->top--;
return 0;
}
2.2.4 栈的遍历【输出】
/*
* function: 顺序栈的输出
* @param [ in]
* @param [out]
* @return 无
*/
void stack_output(StackList *stack)
{
//1,判断栈是否创建
//2,判断栈是否为空
if(NULL==stack || stack->top==-1)
{
puts("output error");
return;
}
//3,输出
for(int i=0;i<=stack->top;i++)
{
printf("%d\t",stack->data[i]);
}
puts("");
}
2.3 顺序栈所有程序
head.h
#ifndef __STACK_HEAD_H__
#define __STACK_HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 4
typedef int datatype;
typedef struct
{
//栈顶
int top;
//数据元素
datatype data[MAXSIZE];
}StackList;
int list_stack_pop(StackList *stack);
StackList *create_stack();
int list_stack_push(datatype e,StackList *stack);
void stack_output(StackList *stack);
#endif
main.c
#include "stack_head.h"
int main(int argc, const char *argv[])
{
StackList *stack=create_stack();
char continu;
datatype e;
int flag;
do
{
//入栈
printf("please enter e:");
scanf("%d",&e);
flag=list_stack_push(e,stack);
if(flag==-1)
break;
printf("Please enter whether you will continue");
scanf(" %c",&continu);
}while(continu!='N'&&continu!='n');
stack_output(stack);
do
{
flag=list_stack_pop(stack);
if(flag==-1)
break;
printf("Please enter whether you will continue");
scanf(" %c",&continu);
}while(continu!='N'&&continu!='n');
stack_output(stack);
return 0;
}
test.c
#include "stack_head.h"
/*
* function: 创建栈
* @param [ in]
* @param [out]
* @return
*/
StackList *create_stack()
{
StackList *stack=(StackList *)malloc(sizeof(StackList));
if(NULL == stack)
{
return NULL;
}
//栈顶置空
stack->top=-1;
memset(stack->data,0,sizeof(stack->data));
return stack;
}
/*
* function: 入栈
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int list_stack_push(datatype e,StackList *stack)
{
//1,判断栈是否创建
//2,判断栈是否为满
if(NULL==stack || stack->top==MAXSIZE-1)
{
puts("push stack error");
return -1;
}
//3,入栈:先加后压
//stack->top++;
stack->data[++stack->top]=e;
return 0;
}
/*
* function: 顺序栈的输出
* @param [ in]
* @param [out]
* @return 无
*/
void stack_output(StackList *stack)
{
//1,判断栈是否创建
//2,判断栈是否为空
if(NULL==stack || stack->top==-1)
{
puts("output error");
return;
}
//3,输出
for(int i=0;i<=stack->top;i++)
{
printf("%d\t",stack->data[i]);
}
puts("");
}
/*
* function: 出栈
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int list_stack_pop(StackList *stack)
{
//1,判断栈是否创建
//2,判断栈是否为空
if(NULL==stack || stack->top==-1)
{
puts("pop error");
return -1;
}
//3,出栈:先弹后减
printf("pop data is:%d\n",stack->data[stack->top--]);
// stack->top--;
return 0;
}
2.4 链栈【借助单链表实现】
顺序栈存在栈满,并且存储数据量较小,所以引出链栈,链栈采用链式存储结构,没有栈满,动态申请空间,多适用于数据量较大的情况。
链栈是借助于单链表实现的。
2.4.1 链栈结构体定义
//定义单链表节点结构体
typedef struct Node
{
//数据域:数据元素
datatype data;
//指针域:存储下一个节点的地址
struct Node *next;
}*LinkStack;
2.4.2 链栈节点创建【单链表节点创建】
/*
* function: 创建一个节点
* @param [ in]
* @param [out]
* @return
*/
LinkStack create_node()
{
LinkStack node=(LinkStack)malloc(sizeof(struct Node));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;//0x10
}
2.4.3 链栈插入【单链表头插】
/*
* function: 链栈的入栈
* @param [ in]
* @param [out]
* @return
*/
LinkStack link_stack_push(datatype e,LinkStack top)
{
//在堆区创建一个节点
LinkStack node=create_node();//在堆区申请一个节点
node->data=e;//数据域赋值为e
//node节点链接到链表中
node->next=top;
top=node;
return top;//因为自定义函数指针的改变不影响实参,需要返回
}
2.4.4 链栈删除【单链表头删】
/*
* function: 头删除
* @param [ in]
* @param [out]
* @return
*/
LinkStack link_stack_pop(LinkStack top)
{
//判断链表是否为空
if(NULL==top)
{
return top;
}
if(top->next==NULL)
{
free(L);
L=NULL;
}
else
{
LinkStack q=top->next;
top->data=q->data;
top->next=q->next;
free(q);
q=NULL;
}
return top;
}
2.4.5 链栈遍历【单链表遍历】
/*
* function: 循环遍历
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int link_output(LinkStack top)
{
//判断是否创建
//判断是否为空
if(NULL==top )
{
return -1;
}
while(top!=NULL)
{
printf("%d\t",top->data);
top=top->next;
}
puts("");
}
2.5 链栈所有程序
head.h
#ifndef __STACK_HEAD_H__
#define __STACK_HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int datatype;
//定义单链表节点结构体
typedef struct Node
{
//数据域:数据元素
datatype data;
//指针域:存储下一个节点的地址
struct Node *next;
}*LinkStack;
LinkStack link_stack_push(datatype e,LinkStack top);
int link_output(LinkStack top);
LinkStack link_stack_pop(LinkStack L);
#endif
main.c
#include "stack_head.h"
int main(int argc, const char *argv[])
{
LinkStack top=NULL;
char continu;
datatype e;
int flag;
do
{
//入栈
printf("please enter e:");
scanf("%d",&e);
top=link_stack_push(e,top);
printf("Please enter whether you will continue");
scanf(" %c",&continu);
}while(continu!='N'&&continu!='n');
link_output(top);
do
{
top=link_stack_pop(top);
printf("Please enter whether you will continue");
scanf(" %c",&continu);
}while(continu!='N'&&continu!='n');
link_output(top);
return 0;
}
teat.c
#include "stack_head.h"
/*
* function: 创建一个节点
* @param [ in]
* @param [out]
* @return
*/
LinkStack create_node()
{
LinkStack node=(LinkStack)malloc(sizeof(struct Node));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;//0x10
}/*
* function: 链栈的入站
* @param [ in]
* @param [out]
* @return
*/
LinkStack link_stack_push(datatype e,LinkStack top)
{
//在堆区创建一个节点
LinkStack node=create_node();//在堆区申请一个节点
node->data=e;//数据域赋值为e
//node节点链接到链表中
node->next=top;
top=node;
return top;//因为自定义函数指针的改变不影响实参,需要返回
}
/*
* function: 循环遍历
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int link_output(LinkStack top)
{
//判断是否创建
//判断是否为空
if(NULL==top )
{
return -1;
}
while(top!=NULL)
{
printf("%d\t",top->data);
top=top->next;
}
puts("");
}
/*
* function: 头删除
* @param [ in]
* @param [out]
* @return
*/
LinkStack link_stack_pop(LinkStack top)
{
//判断链表是否为空
if(NULL==top)
{
return top;
}
if(top->next==NULL)
{
free(L);
L=NULL;
}
else
{
LinkStack q=top->next;
top->data=q->data;
top->next=q->next;
free(q);
q=NULL;
}
return top;
}