栈
**栈:**一种特殊的数据结构,其只答应在固定的一段举行插入和删除元素的操纵。举行数据插入和删除的一端叫栈顶,另一端叫栈底。栈中元素遵照后进先出的原则
栈在逻辑上是线性的,物理结构上也是线性的,属于线性表的一种
压栈:栈的插入数据操纵叫做压栈,进栈,入栈,从栈顶进入
出栈:栈删除数据操纵叫做出栈,从栈顶出
栈一样平常可以由数组和链表实现,相对而言,选用数组会比利用链表的代价小
选用数组来实现栈:
选择用双向链表来实现栈:相比力单链表,双向链表多出一个指针,在差别的操纵系统下,指针的大小是差别的,32位:4字节,64位:8字节,而这些空间的消耗实在是没必要的。
选用单链表实现栈:相比于双向链表,单链表节流了的空间,但是,用单链表实现栈,在每次插入或者删除数据时,都必要举行内存的申请与释放操纵,频繁的申请空间释放空间是会低沉步伐的服从的。
选用数组实现栈:用数组实现栈既解决了双向链表不必要的空间消耗问题也解决了频繁申请与释放空间的问题,固然数组存在性能的消耗,但是相比力另外两种实现方式,这是最优的选择。
栈里面的数据不能被遍历也不能被随机访问,这是由栈的特性决定的(后进先出,只能在一端举行插入与删除操纵)
栈的实现
首先,创建两个文件,一个是Stack.c文件,用来实现函数,一个是Stack.h文件,这里存放对应的头文件、栈的定义与函数的定义。
栈的定义
- typedef int STDataType;//当后面需求变更时,只需要修改int就行,比如要存储字符型,只需要把Int改成char就行。
- typedef struct Stack
- {
- STDataType* arr;
- int capacity;//栈空间的大小
- int top;//栈顶
- }ST;
复制代码 栈的初始化
- //.h文件下
- void StackInit(ST*ps);//初始化栈
复制代码- //.c文件下
- void StackInit(ST* ps)//初始化栈
- {
- ps->arr = NULL;
- ps->capacity = ps->top = 0;
- }
复制代码 栈的销毁
- //.h文件下
- void StackDestroy(ST*ps);//栈的销毁
复制代码- //.c文件下
- void StackDestroy(ST* ps)//栈的销毁
- {
- assert(ps);
- if (ps->arr)
- free(ps->arr);
- ps->arr = NULL;
- ps->capacity = ps->top = 0;
- }
复制代码 入栈
- //.h
- void StackPush(ST*ps,STDataType x);//入栈
复制代码- void StackPush(ST* ps, STDataType x)//入栈
- {
- assert(ps);
- if (ps->capacity==ps->top)//空间不足
- {//当空间大小与有效数据个数相同时表示栈空间用完了
- int newnode = ps->capacity == 0 ? 4 : 2 * ps->capacity;
- STDataType* tmp = (STDataType*)realloc(ps->arr,newnode*sizeof(STDataType));
- assert(tmp);
- ps->arr = tmp;
- ps->capacity = newnode;
- }
- ps->arr[ps->top++] = x;
- }
复制代码 出栈
- //.h
- bool StackEmpty(ST*ps);//判断栈是否位空]
- void StackPop(ST*ps);//出栈
复制代码- //.c
- bool StackEmpty(ST* ps)//判断栈是否位空
- {
- assert(ps);
- return ps->top == 0;
- }
- void StackPop(ST* ps)//出栈
- {
- assert(ps);
- assert(!StackEmpty(ps));//判断栈是否为空
- --ps->top;
- }
复制代码 获取栈顶元素与栈中有用元素个数
- //.h
- STDataType StackTop(ST*ps);//获取栈顶元素
- STDataType STSize(ST*ps);//获取有效元素个数
复制代码- //.h
- STDataType StackTop(ST* ps)//获取栈顶元素
- {
- assert(ps);
- assert(!StackEmpty(ps));
- return ps->arr[ps->top-1];
- }
- STDataType STSize(ST* ps)//获取有效元素个数
- {
- assert(ps);
- return ps->top;
- }
复制代码 完整代码
- //.h文件
- #pragma once
- #include<stdio.h>
- #include<stdlib.h>
- #include<assert.h>
- #include<stdbool.h>
- typedef int STDataType;
- typedef struct Stack
- {
- STDataType* arr;
- int capacity;//栈空间的大小
- int top;//栈顶
- }ST;
- void StackInit(ST*ps);//初始化栈
- void StackDestroy(ST*ps);//栈的销毁
- void StackPush(ST*ps,STDataType x);//入栈
- void StackPop(ST*ps);//出栈
- bool StackEmpty(ST*ps);//判断栈是否位空]
- STDataType StackTop(ST*ps);//获取栈顶元素
- STDataType STSize(ST*ps);//获取有效元素个数
复制代码- //.c文件
- #include"Stack.h"
- void StackInit(ST* ps)//初始化栈
- {
- ps->arr = NULL;
- ps->capacity = ps->top = 0;
- }
- void StackDestroy(ST* ps)//栈的销毁
- {
- assert(ps);
- if (ps->arr)
- free(ps->arr);
- ps->arr = NULL;
- ps->capacity = ps->top = 0;
- }
- void StackPush(ST* ps, STDataType x)//入栈
- {
- assert(ps);
- if (ps->capacity==ps->top)//空间不足
- {
- int newnode = ps->capacity == 0 ? 4 : 2 * ps->capacity;
- STDataType* tmp = (STDataType*)realloc(ps->arr,newnode*sizeof(STDataType));
- assert(tmp);
- ps->arr = tmp;
- ps->capacity = newnode;
- }
- ps->arr[ps->top++] = x;
- }
- void StackPop(ST* ps)//出栈
- {
- assert(ps);
- assert(!StackEmpty(ps));
- --ps->top;
- }
- bool StackEmpty(ST* ps)//判断栈是否位空
- {
- assert(ps);
- return ps->top == 0;
- }
- STDataType StackTop(ST* ps)//获取栈顶元素
- {
- assert(ps);
- assert(!StackEmpty(ps));
- return ps->arr[ps->top-1];
- }
- STDataType STSize(ST* ps)//获取有效元素个数
- {
- assert(ps);
- return ps->top;
- }
复制代码 队列
队列:只答应在一段举行插入数据,在另一端举行插入数据的特殊线性表,队列,先进先出
底层由链表来实现,固然数=数组也可以,但是数组服从低。完整代码如下:
- .c
- #pragma once
- #include<stdio.h>
- #include<stdlib.h>
- #include<assert.h>
- #include<stdbool.h>
- typedef int QDataType;
- typedef struct QueueNode//队列节点
- {
- QDataType data;
- struct QueueNode* next;
- }QueueNode;
- typedef struct Queue
- {
- QueueNode* phead;
- QueueNode* ptail;
- int size;//节点个数
- }Queue;
- void QueueInit(Queue*pq);//队列初始化
- void QueuePush(Queue*pq,QDataType x);//队列插入数据
- bool QueueEmpty(Queue*pq);//判断队列是否为空
- void QueuePop(Queue*pq);//删除队列数据
- QDataType QueueFront(QueueNode*pq);//取对头数据
- QDataType QueueAfter(Queue* pq);//取队尾数据
- int QueueSize(Queue*pq);//取有效数据个数
- void QueueDestroy(Queue*pq);//队列的销毁
复制代码- .c
- #include"Queue.h"
- void QueueInit(Queue* pq)//队列初始化
- {
- assert(pq);
- pq->phead = pq->ptail = NULL;
- pq->size = 0;
- }
- void QueuePush(Queue* pq, QDataType x)//队列插入数据
- {
- assert(pq);
- QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
- assert(newnode);
- newnode->data = x;
- newnode->next = NULL;
- if (pq->phead==NULL)//队列为空
- {
- pq->phead = pq->ptail = newnode;
- }
- else//队列不为空
- {
- pq->ptail->next = newnode;
- pq->ptail = newnode;
- }
- pq->size++;
- }
- bool QueueEmpty(Queue* pq)//判断队列是否为空
- {
- assert(pq);
- return pq->phead == NULL;
- }
- void QueuePop(Queue* pq)//删除队列数据
- {
- assert(pq);
- assert(!QueueEmpty(&pq));
- if (pq->phead==pq->ptail)
- {
- free(pq->phead);
- pq->phead = pq->ptail = NULL;
- }
- else
- {
- QueueNode* next = pq->phead->next;
- free(pq->phead);
- pq->phead = next;
- }
- --pq->size;
- }
- QDataType QueueFront(Queue* pq)//取队头数据
- {
- assert(pq);
- assert(!QueueEmpty(&pq));
- return pq->phead->data;
- }
- QDataType QueueAfter(Queue* pq)//取队尾数据
- {
- assert(pq);
- assert(!QueueEmpty(&pq));
- return pq->ptail->data;
- }
- int QueueSize(Queue* pq)//取有效数据个数
- {
- assert(pq);
- return pq->size;
- }
- void QueueDestroy(Queue* pq)//队列的销毁
- {
- assert(pq);
- assert(!QueueEmpty(&pq));
- QueueNode* pcur = pq->phead;
- while (pcur)
- {
- QueueNode* next = pcur->next;
- free(pcur);
- pcur = next;
- }
- pq->phead = pq->ptail = NULL;
- pq->size = 0;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |