c语言第六课(链表)

本文主要介绍了C语言中链表的相关知识,包括单链表逆序的两种方法(利用三个变量和递归思想)、双向链表和循环链表的结构,还涉及约瑟夫环问题及表达式解析。通过代码示例详细展示了链表操作和表达式计算的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、链表:链式结构的线性表

链表的节点:链表存放的数据内存

节点到组成:你存储的数据+链子(指针)的组合

1、单链表的逆序:

struct Node

{

   int data;     //存储变量区

   struct Node *next;    //因为链表是单向的,创建一个结构体指针指向下一个节点

};

struct LinkList

{

   struct Node *head;    //标记该链表的头地址,用来寻找整个链表

   int len;              //储存链表的长度

};

第一种方法:(利用三个变量)

void Reserve(struct LinkList *list)

{

   struct Node *prev=NULL;   

   struct Node *cur=list->head;   //定义cur指向首地址

   struct Node *Next=list->head->next;  //定义Next指向首地址的下一位

   while(Next!=NULL)   //当Next指向空的时候,结束循环

   {

    cur->next=prev;    //cur指向下一个节点的指针指向prev

    prev=cur;         //将cur的值赋值给prev

    cur=Next;         //cur指向下一个节点

    Next=cur->next;    //Next指向下一个节点

   }

   cur->next=prev;      //再将最后一个节点的指针指向上一个节点   

   list->head=cur;       //将首地址指向cur,至此链表倒序结束

}

第二种方法(用递归的思想解决)

struct Node *Reserve2(struct Node *node)

{

  struct Node *tail;         //定义结构体指针作为尾指针

  if(node->next==NULL)      //当node的next指向空时,结束递归,返回node

  {

    return node;       

  }

  else

  {

   tail=Reserve2(node->next);    //进行递归操作,直到返回值

   node->next->next=node;     //将node的next指针指向的节点指向的下一位指向node

   node->next=NULL;     //将node的下一位指向空

   return tail;            //返回tail,实际上一直返回的是最后一次时返回的node,作为链表逆序后的首地址

  }

}

2、双向链表:带双向头指针的链表

struct Node

{

  ElementType data;

  struct Node* next;

  struct Node* prev;

};

struct DLinkList

{

   struct Node *head;

   struct Node *tail;

   int len;

};

3、循环链表:链表的头指向链表的尾,一般用双向指针表示。

双向循环链表,链表的list->tail. next=list->head   list->head.prev=list->tail 即头的上一个指向尾,尾的下一个指向头

约瑟夫环:每次第三个都删除,直到剩下最后一个

struct LinkStack

{

  DLlist stack;

  ElementType Topdata;

};

typedef struct LinkStack LStack;

int InitLinkStack(LStack *s)

{

    return InitDLinkList(&s->stack);

}

struct Node *GetTop(LStack *s)

{

    return s->stack.tail;

}

void Push(LStack *s,ElementType element)

{

   InsertTail(&s->stack,element);

}

ElementType* Pop(LStack *s)

{

    if(s->stack.tail==NULL)

    {

      return NULL;

    }

    s->Topdata=s->stack.tail->data;

    RemoveByIndex(&s->stack,s->stack.len-1);

    return &s->Topdata;

}

void FreeStack(LStack *s)

{

    FreeDLinkList(&s->stack);

}

  1. 表达式解析:输入“1+2+3=”类似的表达式,输出结果

#include"LinkStack.h"

#include<stdio.h>

#include<stdlib.h>

#define true 1

#define false 0

int IsOper(char c)

{

  switch(c)

  {

    case '+':

    case '-':

    case '*':

    case '/':

    case '=':

    case '(':

    case ')':

      return true;

    default:

      return false;

  }

}

int IsNum(char c)

{

    if(c>='0'&&c<='9')

    return true;

    else

    return false;

}

int Operate(int prev,int next,char symbol)

{

      switch(symbol)

  {

    case '+':return prev+next;

    case '-':return prev-next;

    case '*':return prev*next;

    case '/':

    if(next==0)

    {

        printf("devide zero!\n");

        exit(-1);

    }

    return prev/next;

    default:

      return false;

  }

}

char Percede(char ch1,char ch2)

{

   

    int i=0,j=0;

    switch(ch1)

    {

    case '+':i=0;break;

    case '-':i=1;break;

    case '*':i=2;break;

    case '/':i=3;break;

    case '(':i=4;break;

    case ')':i=5;break;

    case '=':i=6;break;

    default:

      break;

    }

        switch(ch2)

    {

    case '+':j=0;break;

    case '-':j=1;break;

    case '*':j=2;break;

    case '/':j=3;break;

    case '(':j=4;break;

    case ')':j=5;break;

    case '=':j=6;break;

    default:

      break;

    }

    char pre[7][7]=

    {

        {'>','>','<','<','<','>','>'},

        {'>','>','<','<','<','>','>'},

        {'>','>','>','>','<','>','>'},

        {'>','>','>','>','<','>','>'},

        {'<','<','<','<','<','=','0'},

        {'>','>','>','>','0','>','>'},

        {'<','<','<','<','<','0','='}

    };

    return pre[i][j];

}

int main()

{

    LStack Num;

    InitLinkStack(&Num);

    LStack Oper;

    InitLinkStack(&Oper);

    Push(&Oper,'=');

    char str[100]={0};

    scanf("%s",str);

    int i=0;

    while(str[i]!='\0')

    {

        if(IsOper(str[i]))

        {

            switch(Percede(GetTop(&Oper)->data,str[i]))

            {

              case '<':

                 Push(&Oper,str[i]);

                 i++;

                 break;

              case '>':

              int next=*Pop(&Num);

              int prev=*Pop(&Num);

              Push(&Num,Operate(prev,next,*Pop(&Oper)));

              break;

              case '=':

              Pop(&Oper);

                       i++;

                       break;

              default:

              break;

            }

        }

        else if(IsNum(str[i]))

        {

            int lower =str[i]-'0';

            Push(&Num,lower);

            i++;

            while(IsNum(str[i]))

            {

                int num=str[i]-'0';

                int higher=*Pop(&Num);

                Push(&Num,(higher)*10+num);

                i++;

            }

        }

        else if(str[i]==' ')

        {

          while(str[i]==' ')

          {

            i++;

          }

        }

    }

    printf("the answer is %d \n",*Pop(&Num));

   return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值