字符串队列c语言,考研数据结构之栈与队列(C语言实现)

68f7f1fcc3cf

排队

一、栈

定义:只允许一端进行插入或者删除操作的线性表

特点:LIFO后进先出,像是一叠盘子,只能从上放,从上取.

实现: 顺序存储实现和链式存储实现

1.顺序存储实现代码

#include

#define MAX_SIZE 10

typedef struct {

int data[MAX_SIZE];

int top;

}Stack;

/**

* 初始化栈.

* @return 指向栈的指针.

*/

Stack* initStack();

/**

* 压栈.

* @param data 数据.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool push(int data,Stack* stack);

/**

* 出栈.

* @param data 数据.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

int pop(Stack* stack);

/**

* 已满.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool isFull(Stack* stack);

/**

* 已空.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool isEmpty(Stack* stack);

/**

* 展示栈元素.

* @param stack 栈指针.

*/

void showStack(Stack* stack);

int main() {

Stack* stack = initStack();

push(1,stack);

push(2,stack);

push(3,stack);

push(4,stack);

push(5,stack);

pop(stack);

pop(stack);

pop(stack);

pop(stack);

pop(stack);

pop(stack);

}

Stack* initStack() {

static Stack stack;

for(int i =0;i < MAX_SIZE; i++) {

stack.data[i] = 0;

}

stack.top = -1;

return &stack;

}

bool push(int data,Stack* stack) {

if(isFull(stack)) {

return false;

}

stack->data[++stack->top] = data;

showStack(stack);

return true;

}

bool isFull(Stack* stack) {

if(stack->top == MAX_SIZE -1) {

puts("栈已满");

return true;

}

return false;

}

bool isEmpty(Stack* stack) {

if(stack->top == -1){

return true;

}

return false;

}

void showStack(Stack* stack) {

for(int i = 0; i <= stack->top; i++) {

printf("%d ", stack->data[i]);

}

printf("\n");

}

int pop(Stack* stack){

if(isEmpty(stack)) {

puts("栈已空");

return false;

}

int popEle = stack->data[stack->top];

stack->data[stack->top--] = 0;

printf("popEle = %d\n",popEle);

showStack(stack);

return popEle;

}

2.带头结点链式存储实现.

#include

#include

typedef struct Node{

int data;

struct Node* next;

}Stack,Node;

/**

* 初始化栈.

* @return 指向栈的指针.

*/

Stack* initStack();

/**

* 压栈.

* @param data 数据.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool push(int data,Stack* stack);

/**

* 出栈.

* @param data 数据.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

int pop(Stack* stack);

/**

* 已空.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool isEmpty(Stack* stack);

/**

* 展示栈元素.

* @param stack 栈指针.

*/

void showStack(Stack* stack);

/**

* 获取一个节点.

* @param data 数据.

* @return 节点.

*/

Node* getNode(int data);

int main() {

Stack* stack = initStack();

push(1,stack);

push(2,stack);

push(3,stack);

push(4,stack);

push(5,stack);

pop(stack);

pop(stack);

pop(stack);

pop(stack);

pop(stack);

pop(stack);

}

Stack* initStack(){

return getNode(0);

}

Node* getNode(int data){

Node* node = (Node*)malloc(sizeof(Node));

node->data = data;

node->next = NULL;

return node;

}

bool push(int data,Stack* stack) {

Stack* pointer = stack;

Node* node = getNode(data);

node->next = pointer->next;

pointer->next = node;

showStack(stack);

return true;

}

void showStack(Stack* stack) {

Stack* pointer = stack->next;

while(pointer != NULL) {

printf("%d ", pointer->data);

pointer = pointer->next;

}

printf("\n");

}

int pop(Stack* stack) {

if(isEmpty(stack)) {

return -1;

}

Node* freeNode = stack->next;

int popEle = freeNode->data;

stack->next = stack->next->next;

free(freeNode);

printf("popEle = %d\n",popEle);

showStack(stack);

return popEle;

}

bool isEmpty(Stack* stack){

if(stack->next == NULL) {

puts("栈已空");

return true;

}

return false;

}

3.感受

栈代码写起来要比线性表更加简单,以为毕竟栈是受限的线性表,砍掉了一些操作而已。

二、队列

定义: 只允许在一端进行插入,在另一端进行删除的线性表

特点:FIFO先进先出.

实现: 静态存储实现,动态存储实现.

1.静态存储实现的循环队列

#include

#define MAX_SIZE 10

typedef struct Queue{

int data[MAX_SIZE];

int front;

int rear;

}Queue;

/**

* 初始化队列.

* @return 队列指针.

*/

Queue* initQueue();

/**

* 入队.

* @param data 数据.

* @param queue 队列指针.

* @return true 成功,false失败.

*/

bool joinQueue(int data, Queue* queue);

/**

* 出队.

* @param data 数据.

* @param queue 队列指针.

* @return true 成功,false失败.

*/

bool leaveQueue(Queue* queue);

/**

* 判断队列已满.

* @param queue 队列指针.

* @return true 成功,false失败.

*/

bool isFull(Queue* queue);

/**

* 判断空队列.

* @param queue 队列指针.

* @return true 成功,false失败.

*/

bool isEmpty(Queue* queue);

/**

* 展示队列.

* @param queue 队列.

*/

void showQueue(Queue* queue);

int main() {

Queue* queue = initQueue();

joinQueue(1,queue);

joinQueue(2,queue);

joinQueue(3,queue);

joinQueue(4,queue);

joinQueue(5,queue);

joinQueue(6,queue);

joinQueue(7,queue);

joinQueue(8,queue);

joinQueue(9,queue);

joinQueue(10,queue);

leaveQueue(queue);

joinQueue(10,queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

return true;

}

Queue* initQueue() {

static Queue queue;

for(int i =0; i < MAX_SIZE; i++) {

queue.data[i] = 0;

}

queue.front = 0;

queue.rear = 0;

return & queue;

}

bool isFull(Queue* queue) {

if((queue->rear + 1) % MAX_SIZE == queue->front) {

puts("队列已满");

return true;

}

return false;

}

bool isEmpty(Queue* queue) {

if(queue->front == queue->rear) {

puts("队列为空");

return true;

}

return false;

}

void showQueue(Queue* queue) {

int start = queue->front;

int end = queue->rear;

while(end != start){

printf("%d ",queue->data[start]);

start = (start + 1) % MAX_SIZE;

}

printf("\n");

}

bool leaveQueue(Queue* queue) {

if(isEmpty(queue)) {

return false;

}

int ele = queue->data[queue->front];

queue->front = (queue->front + 1) % MAX_SIZE;

printf("leave queue ele = %d\n",ele);

showQueue(queue);

return true;

}

bool joinQueue(int data, Queue* queue) {

if(isFull(queue)) {

return false;

}

queue->data[queue->rear] = data;

queue->rear = (queue->rear + 1) % MAX_SIZE;

showQueue(queue);

return true;

}

2.链式存储实现的队列.

#include

#include

#define MAX_SIZE 10

typedef struct Node{

int data;

struct Node* prior;

struct Node* next;

}Node;

typedef struct Queue{

Node* front;

Node* rear;

}Queue;

/**

* 初始化队列.

* @return 队列指针.

*/

Queue* initQueue();

/**

* 获取节点.

* @param data 数据.

* @return 节点指针.

*/

Node* getNode(int data);

/**

* 加入队列.

* @param data 数据.

* @param queue 队列指针.

* @return true 成功,false失败.

*/

bool joinQueue(int data,Queue* queue);

/**

* 离开队列.

* @param queue 队列指针.

* @return true 成功,false失败.

*/

bool leaveQueue(Queue* queue);

/**

* 展示队列.

* @param queue 队列指针.

*/

void showQueue(Queue* queue);

int main() {

Queue* queue = initQueue();

joinQueue(1,queue);

joinQueue(2,queue);

joinQueue(3,queue);

joinQueue(4,queue);

joinQueue(5,queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

leaveQueue(queue);

}

Queue* initQueue() {

static Queue queue;

Node* node = getNode(0);

node->next = node;

node->prior = node;

queue.front = node;

queue.rear = node;

return &queue;

}

Node* getNode(int data) {

Node* node = (Node*)malloc(sizeof(Node));

node->prior = NULL;

node->next = NULL;

node->data = data;

return node;

}

bool joinQueue(int data,Queue* queue){

Node* node = getNode(data);

Node* pointer = queue->rear;

pointer->next = node;

node->prior = pointer;

node->next = queue->front;

pointer->prior = node;

queue->rear = node;

showQueue(queue);

return true;

}

void showQueue(Queue* queue) {

Node* pointer = queue->front->next;

while(pointer != queue->rear) {

printf("%d ",pointer->data);

pointer = pointer->next;

}

printf("%d\n",pointer->data);

}

bool leaveQueue(Queue* queue) {

if(queue->front == queue->rear) {

puts("队列已空\n");

return false;

}

Node* freeNode = queue->front;

queue->front = queue->front->next;

queue->front->prior = queue->rear;

queue->rear->next = queue->front;

int ele = queue->front->data;

free(freeNode);

printf("leave queue ele = %d\n",ele);

if(queue->front != queue->rear) {

showQueue(queue);

return true;

}

puts("队列已空");

return true;

}

三、栈的应用

中缀表达式转后缀

思想:

用栈存储尚未确定运算顺序的运算符和界限符.

待优化:

因为使用的是字符数组所以,目前只处理单个字符数字'0’,'1'...'9',多位数情况'10'尚不能处理。代码着重体现了中缀转后缀表达式的思想。

#include

#include

typedef struct Node{

char data;

struct Node* next;

}Stack,Node;

/**

* 初始化栈.

* @return 指向栈的指针.

*/

Stack* initStack();

/**

* 压栈.

* @param data 数据.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool push(char data,Stack* stack);

/**

* 出栈.

* @param data 数据.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

char pop(Stack* stack);

/**

* 已空.

* @param stack 栈指针.

* @return true 成功,false失败.

*/

bool isEmpty(Stack* stack);

/**

* 展示栈元素.

* @param stack 栈指针.

*/

void showStack(Stack* stack);

/**

* 获取一个节点.

* @param data 数据.

* @return 节点.

*/

Node* getNode(char data);

/**

* 中缀表达式转后缀表达式.

* @param stack 栈.

* @return 字符串.

*/

char * nifixToPostFix(Stack* stack);

int main() {

Stack* stack = initStack();

char* result = nifixToPostFix(stack);

puts(result);

}

Stack* initStack(){

return getNode(' ');

}

Node* getNode(char data){

Node* node = (Node*)malloc(sizeof(Node));

node->data = data;

node->next = NULL;

return node;

}

bool push(char data,Stack* stack) {

Stack* pointer = stack;

Node* node = getNode(data);

node->next = pointer->next;

pointer->next = node;

showStack(stack);

return true;

}

void showStack(Stack* stack) {

Stack* pointer = stack->next;

while(pointer != NULL) {

printf("%d ", pointer->data);

pointer = pointer->next;

}

printf("\n");

}

char pop(Stack* stack) {

if(isEmpty(stack)) {

return '#';

}

Node* freeNode = stack->next;

char popEle = freeNode->data;

stack->next = stack->next->next;

free(freeNode);

printf("popEle = %d\n",popEle);

showStack(stack);

return popEle;

}

bool isEmpty(Stack* stack){

if(stack->next == NULL) {

puts("栈已空");

return true;

}

return false;

}

// 使用栈存储暂时不能确定顺序的运算符.

char * nifixToPostFix(Stack* stack) {

char input[1024];

char postFixExpression[1024];

char* inputPointer = input;

char* pointer = postFixExpression;

char* string = postFixExpression;

puts("请输入表达式");

gets(input);

while(*inputPointer){

// 操作数直接加入后缀表达式.

char aim = *inputPointer;

if(aim >= '0' && aim <='9') {

*pointer = aim;

pointer++;

}

//遇到‘(’界限符,直接入栈.

if(aim == '(') {

push(aim, stack);

}

// 遇到界限符‘)’,说明之前肯定有‘(’在栈中,弹出栈中所有的运算符

// 并加入后缀表达式,直到遇到‘(’注意左括号不加入表达式.

if(aim == ')') {

char popEle = pop(stack);

while(popEle != '#') {

if(popEle == '('){

break;

}

*pointer = popEle;

pointer++;

popEle = pop(stack);

}

}

//遇到运算符,弹出高于或者等于当前运算符优先级的栈中运算符

//遇到栈空或者(结束,并将当前运算符加入栈中.

if(aim == '+' || aim == '-') {

//所有的运算符都曼度大于等于优先级顾直接弹出.

char popEle = pop(stack);

while(true) {

if(popEle == '#') {

break;

}

if(popEle == '(' ){

push(popEle, stack);

break;

}

*pointer = popEle;

pointer++;

popEle = pop(stack);

}

push(aim, stack);

}

if(aim == '*' || aim == '/') {

char popEle = pop(stack);

while(popEle == '*' || popEle =='/') {

*pointer = popEle;

pointer++;

popEle = pop(stack);

}

if(popEle == '+' || popEle == '-') {

push(popEle, stack);

}

push(aim, stack);

}

inputPointer++;

}

// 最后将队列中的全部运算符弹出并加入后缀表达式.

char popEle = pop(stack);

while(popEle != '#') {

*pointer = popEle;

pointer++;

popEle = pop(stack);

}

*pointer = '\0';

return string;

}

后缀表达式求值

思想:

用栈存储运算数,遍历表达式遇到运算符直接弹出两个运算数进行计算并压栈,重复操作,直到栈中还剩最后一个运算数,这就是结果。

int calculatePostFix(char* expression,Stack* stack) {

char* pointer = expression;

while(*pointer) {

char aim = *pointer;

if(aim >='0' && aim <= '9') {

push(aim - '0',stack);

}

if(aim == '+' ||aim == '-'||aim == '*'||aim == '/'){

int num1 = pop(stack);

int num2 = pop(stack);

int pushEle;

switch(aim){

case '+':{

pushEle = num2 + num1;

break;

}

case '-':{

pushEle = num2 - num1;

break;

}

case '*':{

pushEle = num2 * num1;

break;

}

case '/':{

pushEle = num2 / num1;

break;

}

}

push(pushEle, stack);

}

pointer++;

}

return pop(stack);

}

函数调用栈

递归

四、队列的应用

树的层序遍历.

图的广度优先遍历.

多个进程争抢有限系统资源,FCFS(先来先服务).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值