网站还是app淮南市潘集区信息建设网站
网站还是app,淮南市潘集区信息建设网站,上门做美容的有什么网站,抚州公司做网站1、栈
1.1、栈的概念及结构
栈#xff1a;一种特殊的线性表#xff0c;其只允许在固定的一端进行插入和删除元素操作。__进行数据插入和删除操作的一端称为栈顶#xff0c;另一端称为栈底。__栈中的数据元素遵守__后进先出#xff08;先进后出#xff09;__LIFO#xf…1、栈
1.1、栈的概念及结构
栈一种特殊的线性表其只允许在固定的一端进行插入和删除元素操作。__进行数据插入和删除操作的一端称为栈顶另一端称为栈底。__栈中的数据元素遵守__后进先出先进后出__LIFOLast In First Out的原则。
压栈栈的插入操作叫做进栈/压栈/入栈入数据在栈顶。
出栈栈的删除操作叫做出栈。出数据也在栈顶。 栈stack是一种特殊的线性表是限定仅在一端通常是表尾进行插入和删除操作的线性表。 栈是仅在表尾进行插入、删除操作的线性表。
表尾即an端称为栈顶Top表头即a1端称为栈底Base。
例如 栈 S (a1,a2,a3…an) 总结表尾对应栈顶表头对应栈底。
栈有两种数组栈链表栈。 链式栈
如果是用尾做栈顶尾插尾删要设计成双向链表否则删除数据效率低。如果是用头做栈顶头插头删要设计成单向链表。
两种都可以非要选一种数组栈结构稍微好一点。
数组栈存放数据的方式 链式栈存放数据的方式 尾做栈顶 头做栈顶
总结栈和队列时线性表的子集是插入金额删除位置受限的线性表。
1.2、栈的思考题 问假设与3个元素abc。入栈顺序是abc。 则它们的出栈出栈顺序有几种可能 答案5种可能。下面解释
1c、b、a。原因入栈顺序为a、b、c然后依次取出。
2a、b、c。原因a先入栈然后出栈之后b入栈b出栈最后c入栈c出栈。
3a、c、b。原因a先入栈然后出栈之后b、c入栈最后c、b出栈。
4b、a、c。原因a、b先入栈之后b、a出栈最后c入栈c出栈。
5b、c、a。原因a、b先入栈之后b出栈然后c入栈最后c、a出栈。
2、顺序栈的实现用数组实现 栈主要有以下几个接口函数 初始化栈StackInit销毁StackDestroy栈顶插入数据StackPush栈顶删除数据StackPop取栈顶数据StackTop统计栈种元素个数StackSize判断栈是否为空StackEmpty 2.1、定义结构体和main函数
#pragma once#include stdio.h
#include stdlib.h
#include assert.h
#include stdbool.htypedef int SLDataType;typedef struct Stack
{SLDataType* a;int top; //栈顶int capacity;
};
main函数
#include stack.hint main()
{ST st;return 0;
}2.2、初始化栈
//初始化栈
void StackInit(ST* ps)
{assert(ps);ps-a NULL;ps-top ps-capacity 0;
}2.3、销毁
//销毁
void StackDestory(ST* ps)
{assert(ps);free(ps-a);ps-a NULL;ps-top ps-capacity 0;
}2.4、栈顶插入数据
//栈顶插入数据
void StackPush(ST* ps, SLDataType x)
{assert(ps);if (ps-top ps-capacity){int newcapacity ps-capacity 0 ? 4 : 2 * ps-capacity;SLDataType* tmp (SLDataType*)realloc(ps-a, sizeof(SLDataType) * newcapacity);if (tmp NULL){printf(realloc fail\n);exit(-1);}ps-a tmp;ps-capacity newcapacity;}ps-a[ps-top] x;ps-top;
}2.5、栈顶删除数据
//栈顶删除数据
void StackPop(ST* ps)
{assert(ps);assert(ps-top 0);ps-top--;
}2.6、取栈顶元素
//取栈顶数据
SLDataType StackTop(ST* ps)
{assert(ps);assert(ps-top 0);return ps-a[ps-top - 1];
}2.7、统计栈中元素个数
//统计栈中元素个数
int StackSize(ST* ps)
{return ps-top;
}2.8、判断栈是否为空
//判断栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps-top 0;
}3、全代码展示 这里使用三个文件 stack.h用于结构体、各种函数接口的声明stack.c用于各种函数接口的定义。test.c用于创建链表实现链表。 3.1、stack.h
#pragma once#include stdio.h
#include stdlib.h
#include assert.h
#include stdbool.htypedef int STDataType;typedef struct Stack
{STDataType* a;int top; //栈顶int capacity;
}ST;void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
STDataType StackTop(ST* ps); //取栈顶的数据
int StackSize(ST* ps); //统计栈里面有多少个数据
bool StackEmpty(ST* ps);3.2、stack.c
#include stack.hvoid StackInit(ST* ps)
{assert(ps);ps-a NULL;//初始化时top给的是0意味着top指向栈顶数据的下一个。//初始化时top给的是-1意味着top指向栈顶数据。ps-top 0;ps-capacity 0;
}
void StackDestroy(ST* ps)
{assert(ps);free(ps-a);ps-a NULL;ps-top ps-capacity 0;}
void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps-top ps-capacity){int newCapacity ps-capacity 0 ? 4 : ps-capacity * 2;STDataType* tmp realloc(ps-a, sizeof(STDataType) * newCapacity);if (tmp NULL){printf(realloc fail\n);exit(-1);}ps-a tmp;ps-capacity newCapacity;}ps-a[ps-top] x;ps-top;
}
//删除数据
void StackPop(ST* ps)
{assert(ps);assert(ps-top 0);ps-top--;
}STDataType StackTop(ST* ps) //取栈顶的数据
{assert(ps);assert(ps-top 0);return ps-a[ps-top-1];
}int StackSize(ST* ps) //统计栈里面有多少个数据
{return ps-top;
}bool StackEmpty(ST* ps)
{assert(ps);return ps-top 0;
}3.3、test.c
#include stack.hvoid TestStack()
{ST st;StackInit(st);StackPush(st, 1);StackPush(st, 2);StackPush(st, 3);StackPush(st, 4);StackPush(st, 5);StackPush(st, 6);//遍历栈元素while (!StackEmpty(st)){printf(%d , StackTop(st)); StackPop(st);}StackDestroy(st);
}int main()
{TestStack();return 0;
}4、链栈的实现用链表实现栈
链栈的实现用链表实现栈
前面说过链栈的实现有两种方式
链表头做栈顶这样只需要单链表即可。链表尾做栈顶这样需要双向链表。
这里我们就以单链表的形式实现链表。
以单链表的形式实现链表链表的结构如下
这个样的链表有如下特性
链表的头指针就是栈顶。不需要头结点。基本不存在栈满的情况需要结点就立即申请即可。空栈相当于头指针指向NULL。插入和删除仅在栈顶处执行。
栈主要是用数组实现链栈稍微少一点所以这里直接放全代码不在一个接口一个接口的分析了。 以下是个人写的版本
4.1、stack.h
#pragma once#include stdio.h
#include stdlib.h
#include assert.h
#include stdbool.htypedef int SLDataType;typedef struct Stack
{struct Stack* Next; SLDataType data;
}ST;//销毁
void StackDestory(ST** pps);//插入数据
void StackPush(ST** pps, SLDataType x);//删除数据
void StackPop(ST** pps);//取栈顶元素
SLDataType StackTop(ST** pps);//统计栈里面有多少个数据
int StackSize(ST** pps);//判断栈是否为空
bool StackEmpty(ST** pps);4.2、stack.c
#include stack.h//插入数据
void StackPush(ST** pps, SLDataType x)
{//先扩容ST* newnode (ST*)malloc(sizeof(ST));if (newnode NULL){printf(malloc fail\n);exit(-1);}newnode-data x;newnode-Next *pps;*pps newnode;
}//销毁
void StackDestory(ST** pps)
{ST* cur *pps;while (cur){ST* next cur-Next; free(cur);cur next;}*pps NULL;
}//删除栈顶
void StackPop(ST** pps)
{assert(*pps ! NULL);ST* next (*pps)-Next;free(*pps);*pps next;
}//取栈顶元素
SLDataType StackTop(ST** pps)
{assert(*pps ! NULL);return (*pps)-data;
}//统计栈里面有多少个数据
int StackSize(ST** pps)
{assert(*pps ! NULL);int count 0;ST* cur *pps;while (cur){count;cur cur-Next;}return count;
}//判断栈是否为空
bool StackEmpty(ST** pps)
{assert(pps);return *pps NULL;
}4.3、test.c
#include stack.hint main()
{ST* st NULL;StackPush(st, 1);StackPush(st, 2);StackPush(st, 3);StackPush(st, 4);StackPush(st, 5);StackPush(st, 7);ST** cur st;while (*cur){st *cur;printf(%d , StackTop(st));StackPop(st);}StackDestory(st);return 0;
}5、栈与递归 递归的定义 若一个对象部分的包含它自己或用它自己给自己定义则称这个对象是递归的。若一个过程直接的或间接的调用自己则称这个过程是递归的过程。 以下三种情况常常用到递归方法 递归定义的数学函数。 阶乘函数。斐波那契数列。 具有递归特性的数据结构。 二叉树。广义表。 可递归求解的问题。 迷宫问题。Hanoi塔问题。 递归问题————使用分治法求解 __分治法__对于一个较为复杂的问题能够分解成几个相对简单的且解法相同或类似的子问题来求解。 使用分治法的三个条件 能将一个问题转变为一个新问题而新问题与原问题的解法相同或类同不同的仅是处理的对象且这些对象是变化有规律的。可以通过上述转化而使问题简化。必须有一个明确的递归出口或称为递归边界。 我们再来分析函数递归掉调用过程
调用前系统完成
将实参返回地址等传递给被调用函数。为被调用函数的局部变量分配存储区。将控制转移到被调用函数。
调用后系统完成
保存被调用函数的计算结果。释放被调用函数的数据区。依照被调用函数保存的返回地址将控制转移到调用函数。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90527.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!