数据结构(四)——双向循环链表、栈

本文详细介绍了双向循环链表的定义、创建、插入和遍历操作,并提供了头删法删除节点的练习。此外,还讲解了栈的基本概念,包括顺序栈和链栈的实现,包括入栈、出栈、栈满和栈空的判断。最后,通过一个四则运算器的练习展示了栈在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

一、双向循环链表

1.1 概念

在这里插入图片描述

1.2 操作

1.2.1 定义一个结点结构体

#ifndef _DOUBLELIST_H_
#define _DOUBLELIST_H_
#include <stdio.h>
#include <stdlib.h>
typedef int DataType;
//定义结点结构体
typedef struct doublelist
{
    DataType data;
    struct doublelist *front;   //保存前一个结点的地址
    struct doublelist *next;   //保存后一个结点的地址
}doublelist;

1.2.2 创建一个空的双向循环链表

//创建一个空的双向循环链表
doublelist * DoubleListCreate()
{
    doublelist *head = (doublelist *)malloc(sizeof(doublelist));
    head->front = head;
    head->next = head;
    return head;
}

1.2.3 插入数据

在这里插入图片描述

//插入数据
void DoubleListInsert(doublelist *head,DataType value)
{
    doublelist *tmp = (doublelist *)malloc(sizeof(doublelist));
    tmp->front = NULL;
    tmp->next = NULL;
    tmp->data = value;

    tmp->next = head->next;
    tmp->front = head;

    head->next->front = tmp;
    head->next = tmp;
}

1.2.4 遍历链表

//遍历双向循环链表
void DoubleListPrint(doublelist *head)
{
    doublelist *p = head;
    while(p->next != head)
    {
        p = p->next;
        printf("%d ",p->data);
    }
    putchar(10);
}

练习:头删法删除数据

在这里插入图片描述

//头删法删除数据
DataType DoubleListDelete(doublelist *head)
{
    if(head->next == head)
    {
        printf("双向循环链表为空!\n");
        return (DataType)-1;
    }
    doublelist *tmp = head->next;

    head->next = tmp->next;
    tmp->next->front = head;

    DataType value = tmp->data;
    free(tmp);
    tmp = NULL;
    return value;
}

二、栈 (stack)

2.1 概念

栈的性质:后进先出
栈的操作:
入栈(压栈)push
出栈(单栈)pop

2.2 顺序栈 seqstack

2.2.1 定义数据类型

#ifndef _SEQSTACK_H_
#define _SEQSTACK_H_

#include <stdio.h>
#include <stdlib.h>
#define N 32
typedef int DataType;
typedef struct seqstack
{
    DataType data[N];
    int pos;
}seqstack;

#endif

2.2.2 定义结构体

创建栈

//创建一个空的栈
seqstack* SeqStackCreate()
{
    seqstack *s = (seqstack *)malloc(sizeof(seqstack));
    s->pos = -1;
    return s;
}

2.2.3 判断栈是否为满

//判断栈是否为满
int SeqStackIsFull(seqstack *s)
{
    return s->pos == N -1 ? 1 : 0;
}
判断栈是否为空
//判断栈是否为空
int SeqStackIsEmpty(seqstack *s)
{
    return s->pos == -1 ? 1: 0;
}

2.2.4 入栈

//入栈
void SeqStackPush(seqstack *s,DataType value)
{
    if(SeqStackIsFull(s))
    {
        printf("栈满了!\n");
        return;
    }
    s->pos++;
    s->data[s->pos] = value;
    return;
}

2.2.5 出栈

//出栈
DataType SeqStackPop(seqstack *s)
{
    if(SeqStackIsEmpty(s))
    {
        printf("栈为空!\n");
        return (DataType)-1;
    }
    DataType value = s->data[s->pos];
    s->pos--;
    return value;
}

2.3 链栈(链式栈)

在这里插入图片描述

整体代码

mian.c

//main.c
#include "linkstack.h"
int main(int argc, char const *argv[])
{
    stack s;
    InitStack(&s);
    push(&s,100);
    push(&s,200);
    push(&s,300);
    push(&s,400);
    push(&s,500);
    push(&s,600);
    push(&s,700);

    while(!EmptyStack(&s))
    {
        printf("出栈:%d\n",pop(&s));
    }
    return 0;
}

linkstack.c

//linkstack.c
#include "linkstack.h"
//初始化栈信息
void InitStack(stack *s)
{
    s->length = 0;
    s->top = NULL;
}
//入栈
void push(stack *s,DataType value)
{
    if(NULL == s)
    {
        printf("栈空间分配失败,初始化失败!\n");
        return ;
    }
    Node *tmp = (Node *)malloc(sizeof(Node));
    tmp->next = NULL;
    tmp->data = value;

    tmp->next = s->top;
    s->top = tmp;
    s->length++;
}
//获取栈顶元素
DataType GetTop(stack *s)
{
    if(NULL == s)
    {
        return (DataType)-1;
    }
    if(s->top == NULL)
    {
        return (DataType)-1;
    }
    return s->top->data;
}
//出栈
DataType pop(stack *s)
{
    if(NULL == s)
    {
        return (DataType)-1;
    }
    if(s->top == NULL)
    {
        return (DataType)-1;
    } 
    Node *tmp = s->top;
    s->top = tmp->next;
    DataType value = tmp->data;
    free(tmp);
    tmp = NULL;
    s->length--;
    return value;
}
//判断栈是否为空
int EmptyStack(stack *s)
{
    return s->top == NULL ? 1 : 0;
}
//清空栈
int ClearStack(stack *s)
{
    if(NULL == s)
    {
        return (DataType)-1;
    }
    if(s->top == NULL)
    {
        return (DataType)-1;
    }
    Node *tmp = s->top;
    while(tmp)
    {
        s->top = tmp->next;
        free(tmp);
        tmp = s->top;
        s->length--;
    }     
    return 1;
}

练习 四则运算器

在这里插入图片描述

//判断符号的优先级
int Priority(char ch)
{
    switch (ch)
    {
    case '(':
        return 3;
    case '*':
    case '/':
        return 2;
    case '+':
    case '-':
        return 1;
    default:
        return 0;
    }
}
//四则混合计算器
void calculator()
{
    stack s_sum, s_opt;
    InitStack(&s_sum);
    InitStack(&s_opt);
    char opt[128] = {0};
    printf("请输入表达式:\n");
    scanf("%s",opt);
    int i = 0,tmp = 0,num1,num2;
    while(opt[i] != '\0' || EmptyStack(&s_opt) != 1)
    {
        if(opt[i] >= '0' && opt[i] <= '9')   //运算数
        {
            tmp = tmp *10 + opt[i] - '0';
            i++;
            if(opt[i] < '0' || opt[i] > '9')
            {
                push(&s_sum,tmp);
                tmp = 0;
            }
        }
        else   //操作符
        {
            if(EmptyStack(&s_opt) == 1 || Priority(opt[i]) > Priority(GetTop(&s_opt))||
            (GetTop(&s_opt) == '(' && opt[i] != ')'))
            {
                push(&s_opt,opt[i]);
                i++;
                continue;
            }
            if(GetTop(&s_opt) == '(' && opt[i] == ')')
            {
                pop(&s_opt);
                i++;
                continue;
            }
            if(Priority(opt[i]) <= Priority(GetTop(&s_opt)) ||opt[i] == ')' && GetTop(&s_opt)!= '('||
            opt[i] == '\0' && EmptyStack(&s_opt) != 1)
            {
                switch (pop(&s_opt))
                {
                case '+':
                    num1 = pop(&s_sum);
                    num2 = pop(&s_sum);
                    push(&s_sum,num1 + num2);
                    break;
                case '-':
                    num1 = pop(&s_sum);
                    num2 = pop(&s_sum);
                    push(&s_sum,num2 - num1);
                    break;
                case '*':
                    num1 = pop(&s_sum);
                    num2 = pop(&s_sum);
                    push(&s_sum,num1 * num2);
                    break;
                case '/':
                    num1 = pop(&s_sum);
                    num2 = pop(&s_sum);
                    push(&s_sum,num2 / num1);
                    break;               
                default:
                    break;
                }
            }
        }
    }
    printf("%d\n",GetTop(&s_sum));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值