• 链表


    知识点总结报告

    知识点:

    链表

    (原理)每个存储结点含有数据域和指针域。线性表中每个元素只有一个前驱结点和一个后续元素。链表分为单链表,双链表。

    单链表  

    每个结点类型声明

    typedef struct LNode

    { ElemType data;             //存放元素值

       struct LNode  *next;      //指向后继节点

    }LinkNode;               //单链表结点类型

      插入结点     s->next=p->next;  p->next=s;

      删除结点     q=p->next;     //q临时保存被删结点    p->next=q->next;     //从链表中删除结点q     free(q);         //释放结点q的空间

      建立单链表

    1)头插法

    void CreateListF(LinkNode *&L,ElemType a[ ],int n)

    {  LinkNode *s;

       L=(LinkNode *)malloc(sizeof(LinkNode));

       L->next=NULL;              //创建头结点,其next域置为NULL

       for(int i=0;i<n;i++)          //循环建立数据结点s

       {  s=(LinkNode *)malloc(sizeof(LinkNode));

          s->data=a[i];   //创建数据结点s

          s->next=L->next;        //将结点s插入到原首结点之前,头结点之后

          L->next=s;

        }

    }

    2)尾插法

    void CreateListR(LinkNode *&L,ElemType a[ ],int n)

    {  LinkNode *s,*r;

       L=(LinkNode *)malloc(sizeof(LinkNode));       //创建头节点

       r=L;              //r始终指向尾结点,初始时指向头结点

       for(int i=0;i<n;i++)          //循环建立数据结点s

       {  s=(LinkNode *)malloc(sizeof(LinkNode));

          s->data=a[i];   //创建数据结点s

          r->next=s;        //将结点s插入到结点r之后

          r=s;

        }

        r->next=NULL;       //尾结点的next域置为NULL

    }

    初始化线性表InitList(&L)

    void InitList(LinkNode *&L)

    {  L=(LinkNode *)malloc(sizeof(LinkNode));

       L->next= NULL;       //创建头结点,其next域置为NULL

    }

    销毁线性表DestroyList(&L)

    void DestroyList(LinkNode *&L)

    {    LinkNode *pre=L,*p=L->next;     //pre指向结点p的前驱结点

          while(p!=NILL)           //扫描单链表L

          {   free(pre);            //释放pre结点

              pre=p;                //pre.p同步后移一个结点

              p=pre->next;

         }

        free(pre);                  //循环结束时p为NULL,pre指向尾结点,释放它

    }

    判断线性表是否为空表ListEmpty(L)

    bool ListEmpty(LinkNode *L)

    {    return(L->next==NULL);

    }

    求线性表的长度ListLength(L)

    int ListLength(LinkNode *L)

    {     int n=0;

          LinkNode *p=L;            //p指向头结点,n置为0(即头结点的序号为0)

          wile(p->next!=NULL)

          {  n++;

             p=p->next;

          }                               //循环结束时,p指向尾结点,其序号n为结点个数

          return(n);

    }

    输出线性表DispList(L)

    void DispList(LinkNode *L)

    {   LinkNode *p=L->next;          //p指向首结点

        while(p!=NULL)

      {  printf("%d ",p->data);

         p=p->next;

     }

        printf("\n");

    }

    求线性表中的某个数据元素值GetElem(L,i,&e)

    bool GetElem(LinkNode *L,int i,ElemType &e)

    {  int j=0;

          LinkNode *p=L;      //p指向头结点,j置为0(即头结点的序号为0)

      if(i<=0)return false;     //i错误返回假

      while(j<i&&p!=NULL)    //找第i个结点p

      {  j++;

        p=p->next;

      }

      if(p==NULL)        //不存在第i个数据结点,返回false

        return false;

      else            //存在第i个结点,返回true

      {  e=p->data;

        return true;

      }

    }

    按元素值查找LocateElem(L,e)

    int LocateElem(LinkNode *L,Elemtype e)

    {  int i=1;

      LinkNode *p=L->next;      //p指向首结点,i置为1(首结点序号为1)

      while(p!=NULL&&p->data!=e)  //查找data值为e的结点,序号为i

      {  p=p->next;

         i++;

      }

      if(p==NULL)      //不存在值为e的结点,返回0

        return(0);

      else          //存在值为e的结点,返回逻辑序号i

        return(i);

    }

    插入数据元素ListInsert(&L,i,e)

    bool ListInsert(LinkNode *&L,int i,ElemType e)

    {  int j=0;

      LinkNode *p=L,*s;    //p指向头结点,j置为0(头结点序号为0)

      if(i<=0) return false;    //i错误返回false

      while(j<i-1&&p!=NULL)  //查找第i-1个结点p

      {  j++;

        p=p->next;

      }

      if(p==NULL)      //未找到第i-1个结点,返回false

        return false;

      else          //找到第i-1个结点p,插入新结点并返回true

      {  s=(LinkNode *)malloc(sizeof(LinkNode));

        s->data=e;    //创建新结点s,其data域置为e

        s->next=p->next;  //将结点s插入到结点p之后

        p->next=s;

        rerturn true;

      }

    }

    删除数据元素ListDelete(&L,i,&e)

    bool ListDelete(LinkNode *&L,int i,ElemType &e)

    {  int j=0;

      LinkNode *p=L,*q;    //p指向头结点,j置为0(头结点序号为0)

      if(i<=0) return false;    //i错误返回false

      while(j<i-1&&p!=NULL)    //查找第i-1个结点

      {  j++;

        p=p->next;

      }

      if(p==NULL)      //未找到第i-1个结点,返回false

        return false;

      else          //找到第i-1个结点p

      {  q=p->next;      //q指向第i个结点

        if(q==NULL)      //若不存在第i个结点,返回false

          return false;    

        e=q->data;

        p->next=q->next;    //从单链表中删除q结点

        free(q);        //释放q结点

        return true;      //返回true表示成功删除第i个结点

      }

    }

    (例题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1216

     

    Problem Description
    After the 1997/1998 Southwestern European Regional Contest (which was held in Ulm) a large contest party took place. The organization team invented a special mode of choosing those participants that were to assist with washing the dirty dishes. The contestants would line up in a queue, one behind the other. Each contestant got a number starting with 2 for the first one, 3 for the second one, 4 for the third one, and so on, consecutively.
    The first contestant in the queue was asked for his number (which was 2). He was freed from the washing up and could party on, but every second contestant behind him had to go to the kitchen (those with numbers 4, 6, 8, etc). Then the next contestant in the remaining queue had to tell his number. He answered 3 and was freed from assisting, but every third contestant behind him was to help (those with numbers 9, 15, 21, etc). The next in the remaining queue had number 5 and was free, but every fifth contestant behind him was selected (those with numbers 19, 35, 49, etc). The next had number 7 and was free, but every seventh behind him had to assist, and so on.

    Let us call the number of a contestant who does not need to assist with washing up a lucky number. Continuing the selection scheme, the lucky numbers are the ordered sequence 2, 3, 5, 7, 11, 13, 17, etc. Find out the lucky numbers to be prepared for the next contest party.
     

     

    Input
    The input contains several test cases. Each test case consists of an integer n. You may assume that 1 <= n <= 3000. A zero follows the input for the last test case.
     

     

    Output
    For each test case specified by n output on a single line the n-th lucky number.
     

     

    Sample Input
    1 2 10 20 0
     

     

    Sample Output
    2 3 29 83

    题目分析:

     

    开始有很多人从2开始编号,依次为2,3,4,5,6.。。。

    每次删除元素,从第一个开始删, 2,那么每隔2个删除那个元素,,于是删除了 4,6,8,10, 现在数组变成 2,3,5,7,9,11,13,15,17,19,21。。

    然后从3开始删除 ,每隔3个删除删除元素 ,,于是删除了9,15,21, 现在变成 2,3,5,7,11,13,17,19...

    然后从5开始删除每隔5个删除一个 于是删除了 19,35,49。根据题目的数据范围,只要求到第3000个数就行。

    题解代码:

    #include<stdio.h>
    #include<string.h>
    #define M 34000
    int n,num[M],ss[3001],t=0;
    int main()
    {
        int i,j,k;
        memset(num,0,sizeof(num));
        for(i=2;i<M;i++)
        {
            if(!num[i])
            {
                ss[t++]=i;k=0;
                for(j=i+1;j<M;j++)
                if(!num[j])
                {
                    k++;
                    if(k==i)
                    {
                        k=0;
                        num[j]=1;
                    }
                }
            }
            if(t==3000)
            {break;}
        }
        while(scanf("%d",&n),n!=0)
        {
            printf("%d\n",ss[n-1]);
        }
        return 0;
    }

     

    ---恢复内容结束---

  • 相关阅读:
    ubuntu16.04源码安装openssh-7.9 openssl-1.1.1
    shell脚本ping IP
    MariaDB-5.5.56 主主复制+keepalived高可用
    十五 数组与指针 推算程序结果
    十六 推算程序结果 结构体指针
    十七 括号表达式 最右为终值
    十八 二维数组赋指针
    十九 程序找错 结构体内的指针使用前要确定指向
    C语言:十九 程序找错 结构体内的指针使用前要确定指向
    C语言:二十 程序找错
  • 原文地址:https://www.cnblogs.com/li1997/p/8335856.html
Copyright © 2020-2023  润新知