- 什么是栈,栈有什么特性?
栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作.
进行数据插入和删除操作的一端称为栈顶,另一端称为栈底.栈中元素遵循后进先出LIFO(Last In First Out)的原则. - 请用C语言实现一个动态栈
stack.h
#pragma once
typedef int STDataType;
typedef struct Stack
{
STDataType* arr;
int size;
int capacity;
}Stack;
void StackInit(Stack* s, int capacity);
void StackPush(Stack* s,STDataType data);
void StackPop(Stack* s);
STDataType StackTop(Stack* s);
int StackEmpty(Stack* s);
int StackSize(Stack* s);
int StackCapacity(Stack* s);
void StackDestroy(Stack* s);
void CheckCapacity(Stack* s);
stack.c
#include "stack.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
void StackInit(Stack* s,int capacity) {
assert(s);
s->arr = (STDataType*)malloc(sizeof(STDataType)*capacity);
if (s->arr == NULL)
{
assert(0);
return;
}
s->capacity = capacity;
s->size = 0;
}
void StackPush(Stack* s,STDataType data) {
assert(s);
if (s->capacity == s->size)
{
CheckCapacity(s);
}
s->arr[s->size++] = data;
}
void StackPop(Stack* s) {
assert(s);
if (StackEmpty(s))
return;
s->size -= 1;
}
STDataType StackTop(Stack* s) {
assert(s);
return s->arr[s->size-1];
}
int StackEmpty(Stack* s) {
assert(s);
return s->size == 0;
}
int StackSize(Stack* s) {
assert(s);
return s->size;
}
int StackCapacity(Stack* s) {
assert(s);
return s->capacity;
}
void StackDestroy(Stack* s) {
if (s->arr) {
free(s->arr);
}
s->capacity = 0;
s->size = 0;
}
void CheckCapacity(Stack* s) {
assert(s);
int newcapacity = 2 * s->capacity;
STDataType* pTemp = (STDataType*)malloc(sizeof(STDataType)*newcapacity);
if (pTemp == NULL) {
assert(0);
return;
}
for (int i = 0; i < s->size; i++) {
pTemp[i] = s->arr[i];
}
free(s->arr);
s->arr = pTemp;
s->capacity = newcapacity;
}
int main() {
Stack s;
StackInit(&s,3);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
printf("%d\n", StackSize(&s));
printf("%d\n", StackTop(&s));
StackPush(&s, 4);
StackPush(&s, 5);
printf("%d\n", StackSize(&s));
printf("%d\n", StackTop(&s));
StackPop(&s);
printf("%d\n", StackSize(&s));
printf("%d\n", StackTop(&s));
StackDestroy(&s);
return 0;
}
测试结果:
-
为什么将递归程序转化成循环时需要用到栈?
函数递归和栈的特性非常相似
递归之所以可以采用非递归方法实现是因为可以用栈的方式
如果你采用递归时 是由系统管理函数栈
而要写成非递归时必须由你自已来管理一个栈.
递归的本质就是栈 -
什么是队列,队列有什么特性?栈和队列有什么区别?
只允许在一端进行插入数据,在另一端进行删除数据操作的特殊线性表.
队列具有先进先出FIFO(First In First Out).
入队列:进行插入操作的一端称为队尾.
出队列:进行删除操作的一端称为队头.
栈和队列有什么区别
队列(Queue):是限定只能在表的一端进行插入和另一端删除操作的线性表
栈(Stack):是限定之能在表的一端进行插入和删除操作的线性表队列和栈的规则
队列:先进先出
栈:先进后出
队列和栈的遍历数据速度
队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快
栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,遍历数据时需要微数据开辟临时空间,保持数据在遍历前的一致性 -
请用C语言实现一个队列
Queue.h
#pragma once
typedef int QUDataType;
typedef struct QueueNode
{
struct QueueNode* _next;
QUDataType _data;
}QueueNode;
typedef struct Queue
{
QueueNode* _front;
QueueNode* _back;
}Queue;
void QueueInit(Queue* pq);
void QueueDstory(Queue* pq);
QueueNode* BuyQueueNode(QUDataType x);
void QueuePush(Queue* pq,QUDataType x);
void QueuePop(Queue* pq);
QUDataType QueueFront(Queue* pq);
QUDataType QueueBack(Queue* pq);
int QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
Queue.c
#include "Queue.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
void QueueInit(Queue* pq) {
assert(pq);
pq->_front = pq->_back = NULL;
}
void QueueDstory(Queue* pq) {
assert(pq);
QueueNode* pDelNode = pq->_front;
if (QueueSize(pq)) {
QueuePop(pq);
}
free(pq->_front);
free(pq->_back);
pq->_front = pq->_back = NULL;
}
QueueNode* BuyQueueNode(QUDataType x) {
QueueNode* PNewNode = (QueueNode*)malloc(sizeof(QueueNode));
if (NULL == PNewNode) {
assert(0);
return;
}
PNewNode->_data = x;
PNewNode->_next = NULL;
return PNewNode;
}
void QueuePush(Queue* pq, QUDataType x) {
assert(pq);
QueueNode* pNewNode = BuyQueueNode(x);
if (QueueEmpty(pq)) {
pq->_front = pq->_back = pNewNode;
}
else {
pq->_back->_next = pNewNode;
pq->_back = pNewNode;
}
}
void QueuePop(Queue* pq) {
assert(pq);
if (QueueEmpty(&pq))
return;
QueueNode* pDelNode = pq->_front;
if (pq->_front == pq->_back) {
pq->_front = pq->_back = NULL;
}
else
{
pq->_front = pq->_front->_next;
}
free(pDelNode);
}
QUDataType QueueFront(Queue* pq) {
assert(pq);
return pq->_front->_data;
}
QUDataType QueueBack(Queue* pq) {
assert(pq);
return pq->_back->_data;
}
int QueueEmpty(Queue* pq) {
return NULL == pq->_front;
}
int QueueSize(Queue* pq) {
assert(pq);
QueueNode* pCur = pq->_front;
int size = 0;
while (pCur) {
size++;
pCur = pCur->_next;
}
return size;
}
int main() {
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
printf("front = %d\n", QueueFront(&q));
printf("back = %d\n", QueueBack(&q));
printf("size = %d\n", QueueSize(&q));
QueuePop(&q);
printf("front = %d\n", QueueFront(&q));
printf("back = %d\n", QueueBack(&q));
printf("size = %d\n", QueueSize(&q));
QueueDstory(&q);
return 0;
}
测试结果: