1.顺序表实现
#include<stdio.h>
#include<stdlib.h>
typedef int STDataType;
//顺序结构实现:实现一个更简单的顺序表
//可以调用顺序表接口来实现
typedef struct stack
{
STDataType* _data;
int _size;
int _capacity;
}stack;
void initStack(stack* st)
{
//空栈
if (st == NULL)
return;
st->_data = NULL;
st->_size = st->_capacity = 0;
}
void checkCapacity(stack* st)
{
if (st->_size == st->_capacity)
{
int newCap = st->_capacity == 0 ? 1 : 2 * st->_capacity;
st->_data = (STDataType*)realloc(st->_data,sizeof(STDataType)*newCap);
st->_capacity = newCap;
}
}
void stackPush(stack* st, STDataType val)//入栈
{
//尾插
if (st == NULL)
return;
checkCapacity(st);
st->_data[st->_size++] = val;
}
void stackPop(stack* st)
{
//尾删
if (st == NULL || st->_size == 0)
return;
--st->_size;
}
int stackSize(stack* st)
{
if (st == NULL)
return 0;
return st->_size;
}
int stackEmpty(stack* st)
{
if (st == NULL || st->_size)
return 1;
else
return 0;
}
STDataType stackTop(stack* st)
{
return st->_data[st->_size - 1];
}
void test()
{
stack st;
initStack(&st);
}
int main()
{
test();
return 0;
}
2.队列
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
不带头非循环单向(头尾指针)
入队:尾插
出队:头删
#include<stdio.h>
#include<stdlib.h>
//队列:带有尾指针的单链表
typedef int QDaTaType;
typedef struct QNode
{
QDaTaType _data;
struct QNode* _next;
};
typedef struct Queue
{
//头尾指针
struct QNode* _head;
struct QNode* _tail;
int _size;
}Queue;
void initQueue(Queue* q)
{
//空队列
if (q == NULL)
return;
q->_head = q->_tail = NULL;
q->_size = 0;
}
struct QNode* creatNode(QDaTaType val)
{
struct QNode* node = (struct QNode*)malloc(sizeof(struct QNode));
node->_data = val;
node->_next = NULL;
}
void queuePush(Queue* q, QDaTaType val)//入队
{
if (q == NULL)
return;
//尾插
struct QNode* node = creatNode(val);
//第一个节点
if (q->_head == NULL)
q->_head = q->_tail = node;
else
{
q->_tail->_next = node;
q->_tail = node;
}
++q->_size;
}
void queuePop(Queue* q)//出队
{
if (q == NULL || q->_head == NULL)
return;
//头删
struct QNode *next = q->_head->_next;
free(q->_head);
q->_head = next;
if (q->_head == NULL)
q->_tail = NULL;//空队列
--q->_size;
}
QDaTaType queueFront(Queue* q)
{
return q->_head->_data;
}
QDaTaType queueBack(Queue* q)
{
return q->_tail->_data;
}
int queueEmpty(Queue* q)
{
return q->_head == NULL;
}
int queueSize(Queue* q)
{
if (q == NULL)
return 0;
return q->_size;
//遍历
}
void test()
{
struct Queue q;
initQueue(&q);
}
栈和队列面试题
1. 括号匹配问题。
bool isValid(char * s)
{
//用栈实现
int map[3][2]={{'(',')'},{'[',']'},{'{','}'}};
int n=strlen(s);
int stk[n+1];
int top=0;
if(n%2==1)
return false;
while(*s)
{
int flag=0;
//左括号:入栈
for(int i=0;i<3;++i)
{
if(*s==map[i][0])
{
stk[top++]=*s;
//判断下一个
++s;
flag=1;
break;
}
}
//右括号
if(flag==0)
{
if(top==0)
return false;//空栈无法取出元素,故必须要判断
//取出栈顶元素
int topChar=stk[top-1];
--top;
//找出当前字符*s对应的左括号
for(int i=0;i<3;++i)
{
if(map[i][1]==*s)
{
if(topChar==map[i][0])
{
//判断下一个字符
++s;
break;
}
else
return false;
}
}
}
bool isValid(char * s)
{
char arr[128]={0};
arr[')']='(';
arr[']']='[';
arr['}']='{';//右边映射左边
int n=strlen(s);
int stk[n+1];
int top=0;
while(*s)
{
int flag=0;
if(*s=='('||*s=='['||*s=='{')
{
stk[top++]=*s;
++s;
flag=1;
}
//右括号
if(flag==0)
{
if(top==0)
return false;
//取出栈顶
char topChar=stk[top-1];
--top;
if(arr[*s]==topChar)
{
++s;
}
else
return false;
}
}
return top==0;
}
2. 用队列实现栈。
一个队列的做法
#include<stdio.h>
#include<stdlib.h>
//队列:带有尾指针的单链表
typedef int QDaTaType;
typedef struct QNode
{
QDaTaType _data;
struct QNode* _next;
}QNode;
typedef struct Queue
{
//头尾指针
struct QNode* _head;
struct QNode* _tail;
int _size;
}Queue;
void initQueue(Queue* q)
{
//空队列
if (q == NULL)
return;
q->_head = q->_tail = NULL;
q->_size = 0;
}
struct QNode* creatNode(QDaTaType val)
{
struct QNode* node = (struct QNode*)malloc(sizeof(struct QNode));
node->_data = val;
node->_next = NULL;
return node;
}
void queuePush(Queue* q, QDaTaType val)//入队
{
if (q == NULL)
return;
//尾插
struct QNode* node = creatNode(val);
//第一个节点
if (q->_head == NULL)
q->_head = q->_tail = node;
else
{
q->_tail->_next = node;
q->_tail = node;
}
++q->_size;
}
void queuePop(Queue* q)//出队
{
if (q == NULL || q->_head == NULL)
return;
//头删
struct QNode *next = q->_head->_next;
free(q->_head);
q->_head = next;
if (q->_head == NULL)
q->_tail = NULL;//空队列
--q->_size;
}
QDaTaType queueFront(Queue* q)
{
return q->_head->_data;
}
QDaTaType queueBack(Queue* q)
{
return q->_tail->_data;
}
int queueEmpty(Queue* q)
{
return q->_head == NULL;
}
int queueSize(Queue* q)
{
if (q == NULL)
return 0;
return q->_size;
//遍历
}
void queueDestroy(Queue* q)
{
QNode* cur=q->_head;
while(cur)
{
QNode* next=cur->_next;
free(cur);
cur=next;
}
q->_head=q->_tail=NULL;
}
typedef struct {
//队列成员
struct Queue q;//定义一个q的队列
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate() {
//动态创建
MyStack* pst=(MyStack*)malloc(sizeof(MyStack));//栈上的结构体变量
initQueue(&pst->q);//结构体变量的成员
return pst;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
queuePush(&obj->q,x);
}
/** Removes the element on top of the stack and returns that element. */
//一个队列的做法
int myStackPop(MyStack* obj) {//出队
int n=queueSize(&obj->q);
while(n>1)
{
//出队,入队
int front=queueFront(&obj->q);//队头元素
queuePop(&obj->q);
queuePush(&obj->q,front);
--n;
}
int top=queueFront(&obj->q);
queuePop(&obj->q);
return top;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {
return queueBack(&obj->q);
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
return queueEmpty(&obj->q);
}
void myStackFree(MyStack* obj) {
queueDestroy(&obj->q);
free(obj);
}
两个队列的做法
typedef struct {
struct Queue q1;
struct Queue q2;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate() {
MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
initQueue(&pst->q1);
initQueue(&pst->q2);
return pst;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
//非空队列入栈
if(!queueEmpty(&obj->q1))
queuePush(&obj->q1,x);
else
queuePush(&obj->q2,x);
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
int top;
if(!queueEmpty(&obj->q1))
{
int n=queueSize(&obj->q1);
while(n>1)
{
//出队,入队
int front=queueFront(&obj->q1);
queuePop(&obj->q1);
queuePush(&obj->q2,front);
--n;
}
top=queueFront(&obj->q1);
queuePop(&obj->q1);
}
else
{
int n=queueSize(&obj->q2);
while(n>1)
{
int front=queueFront(&obj->q2);
queuePop(&obj->q2);
queuePush(&obj->q1,front);
--n;
}
top=queueFront(&obj->q2);
queuePop(&obj->q2);
}
return top;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {//栈顶元素
if(!queueEmpty(&obj->q1))
return queueBack(&obj->q1);
else
return queueBack(&obj->q2);
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
return queueEmpty(&obj->q1)&&queueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
queueDestroy(&obj->q1);
queueDestroy(&obj->q2);
free(obj);
}
3. 用栈实现队列
4. 设计循环队列.
typedef struct {
//对头元素的位置
int _front;
//队尾元素的下一个位置
int _rear;
//队列的容量
int _k;
//存放元素空间的首地址
int * _data;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
cq->_data=(int*)malloc(sizeof(int)*(k+1));
cq->_k=k;
cq->_front=cq->_rear=0;
return cq;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->_front==obj->_rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
//rear+1 % 空间的长度
return (obj->_rear+1)%(obj->_k+1)==obj->_front;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//队列已满,不能入队
if(myCircularQueueIsFull(obj))
return false;
//队尾入队
obj->_data[obj->_rear++]=value;
//判断队尾是否越界[0,k]
if(obj->_rear>obj->_k)
obj->_rear=0;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//队列为空,出队失败
if(myCircularQueueIsEmpty(obj))
return false;
//队头出队
obj->_front++;
//判断队头是否越界
if(obj->_front>obj->_k)
obj->_front=0;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->_data[obj->_front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
if(obj->_rear!=0)
return obj->_data[obj->_rear-1];
else
//rear为0,队尾元素在数组的末尾
return obj->_data[obj->_k];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->_data);//队列当中数组的空间
free(obj);//队列空间
}
//给有效元素的做法fa
```c
typedef struct {
//对头元素的位置
int _front;
//队尾元素的下一个位置
int _rear;
//队列的容量
int _k;
//存放元素空间的首地址
int * _data;
int _size;//有效元素的个数
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
cq->_data=(int*)malloc(sizeof(int)*k);
cq->_k=k;
cq->_front=cq->_rear=0;
cq->_size=0;
return cq;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->_size==0;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return obj->_size==obj->_k;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//队列已满,不能入队
if(myCircularQueueIsFull(obj))
return false;
//队尾入队
obj->_data[obj->_rear++]=value;
//判断队尾是否越界[0,k)
if(obj->_rear>=obj->_k)
obj->_rear=0;
obj->_size++;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//队列为空,出队失败
if(myCircularQueueIsEmpty(obj))
return false;
//队头出队
obj->_front++;
//判断队头是否越界
if(obj->_front>=obj->_k)
obj->_front=0;
obj->_size--;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->_data[obj->_front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
if(obj->_rear!=0)
return obj->_data[obj->_rear-1];
else
//rear为0,队尾元素在数组的末尾
return obj->_data[obj->_k-1];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->_data);//队列当中数组的空间
free(obj);//队列空间
}