数据结构与算法期末考试大题题库

3 顺序表-考试题库

3.1顺序表-非0前移

将顺序表中所有非零元素依次移到表的前端。

【输入形式】

第一行输入整数N表示表长;

第二行输入N个整数,可包含零。

【输出形式】

输出将非零元素移到前端的表中元素,以空格作为分隔。

【样例输入】

6

2 0 -1 0 5 8

【样例输出】

2 -1 5 8 0 0

int deleteList(Sqlist *L,int i)
{
   ElemType *q;
   if(i<0||i>L->length) return 0;
   for(q=L->slist+i;q<L->slist+L->length;q++)
        *q=*(q+1);
   L->length--;
   return 1;
}
//0后移
void houyi(Sqlist *L)
{
    int i;
    for(i=0;i<L->length;i++){
        if(L->slist[i]==0){
            deleteList(L,i);
            L->slist[L->length++]=0;
        }
    }
}
int main()
{
    Sqlist s;
    ElemType e;
    int i;
    initList(&s);
    inputList(&s);
    houyi(&s);
    printList(&s);
}
3.2 顺序表-递增插入

设有递增有序顺序表,实现其插入元素后依然有序。

【输入形式】

第一行输入一个N(N不大于100);

第二行输入N个整数(假设输入序列按照递增顺序,以空格分隔);

第三行输入一个整数M(欲插入数据);

【输出形式】

输出插入M后的顺序表。

【样例输入】

5

12 25 35 98 125

77

【样例输出】

12 25 35 77 98 125

//递增插入=查找+插入
int insertList(Sqlist *L,ElemType e)
{
    int i,j;
    for(i=0;i<L->length&&L->slist[i]<e;i++);
    for(j=L->length;j>i;j--)
        L->slist[j]=L->slist[j-1];
    L->slist[i]=e;
    L->length++;
    return 1;
}
int main()
{
    Sqlist s;
    ElemType e;
    int i;
    initList(&s);
    inputList(&s);
    scanf("%d",&e);
    insertList(&s,e);
    printList(&s);
}
3.3顺序表-查找最小值
//查找最小值
int searchSqMin(SqList *L)
{
    int i,j,min;
    min=L->slist[0];
    for(i=1;i<L->length;i++){
        if(L->slist[i]>min){
            min=L->slist[i];
            j=i;
        }
    }
    return j+1;
}
3.4顺序表-差集并集

设有两个用顺序表表示的有序集合,输出它们的并集,要求仍然保持有序。

【输入形式】

第一行输入两个整数N和M(不大于100),分别表示两个集合的长度;

第二行输入第一个集合的N个元素(递增有序);

第三行输入第二个集合的M个元素(递增有序);

【输出形式】

输出两个集合的并集(仍然保持有序),元素之间以空格分隔。

【样例输入】

5 4

-3 2 4 7 20

2 3 4 5

【样例输出】

-3 2 3 4 5 7 20

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define INIT_SIZE 50
#define INCREM 10
#define OK 1
#define ERROR 0

//定义
typedef int ElemType;//元素类型
typedef struct {
    int *slist;//首地址
    int length;//当前长度
    int listsize;//存储空间
}Sqlist;//顺序表

//初始化
int initList(Sqlist *L)
{
    L->slist=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
    if(!L->slist) return ERROR;
    L->length=0;
    L->listsize=INIT_SIZE;
    return OK;
}

//输入
int inputList(Sqlist *a,Sqlist *b)
{
    int i;
    scanf("%d",&a->length);
    scanf("%d",&b->length);
    for(i=0;i<a->length;i++)
        scanf("%d",&a->slist[i]);
    for(i=0;i<b->length;i++)
        scanf("%d",&b->slist[i]);
    return OK;
}

//打印
void printList(Sqlist *L)
{
    for(int i=0;i<L->length;i++)
        printf("%d ",L->slist[i]);
}
//差集
void chaji(Sqlist *a,Sqlist *b,Sqlist *c)
{
    int i,j,flag;
    c->length=0;
    for(i=0;i<a->length;i++)
    {
        flag=0;
        for(j=0;j<b->length;j++)
            if(b->slist[j]==a->slist[i])
               flag++;
        if(flag==0)
            c->slist[c->length++]=a->slist[i];
    }
}
//并集
void unionList(Sqlist *a,Sqlist *b,Sqlist *c)
{
    int i,j,flag;
    c->length=0;
     ElemType temp;
    for(i=0;i<a->length;i++)
        c->slist[c->length++]=a->slist[i];
     for(i=0;i<b->length;i++){
          flag=0;
         for(j=0;j<a->length;j++)
         if(b->slist[i]==a->slist[j])
            flag++;
         if(flag==0)
         c->slist[c->length++]=b->slist[i];
     }
     //冒泡排序
     for(i=0;i<c->length-1;i++){
         for(j=0;j<c->length-i-1;j++) {
             if(c->slist[j]>c->slist[j+1]){
                 temp=c->slist[j];
                 c->slist[j]=c->slist[j+1];
                 c->slist[j+1]=temp;
             }
         }
     }
}
int main()
{
    Sqlist a,b,c;
    initList(&a);
    initList(&b);
    initList(&c);
    inputList(&a,&b);
    chaji(&a,&b,&c);
    if(c.length)
         printList(&c);
    else
        printf("*");
}
3.5 顺序表-删除重复

设一顺序表有若干元素,编写程序实现删除表中值重复的元素,即重复元素只保留一个。

【输入形式】

第一行输入一个N(N不大于100),表示顺序表的长度;

第二行输入N个整数,表示顺序表元素;

【输出形式】

输出去重后的顺序表。

【样例输入】

7

2 2 2 3 3 2 2

【样例输出】

2 3

int deleteList(Sqlist *L,int i)
{
   ElemType *q;
   if(i<0||i>L->length) return 0;
   for(q=L->slist+i;q<L->slist+L->length;q++)
        *q=*(q+1);
   L->length--;
   return 1;
}
//去除重复元素
int deleteRepeat(Sqlist *L)
{
    int i,j;
    for(i=0;i<L->length;i++){
        for(j=i+1;j<L->length;j++){
            if(L->slist[i]==L->slist[j]){
                deleteList(L,j);
                j--;
            }
        }
    }
}

int main()
{
    Sqlist s;
    ElemType e;
    int i;
    initList(&s);
    inputList(&s);
    deleteRepeat(&s);
    printList(&s);
}
3.6 顺序表-约瑟夫问题

约瑟夫环问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀的顺序是:5,4,6,2,3,1。

【输入形式】

输入两个正整数N和M,N表示N个人,M表示报数到M;

【输出形式】

输出依次出列的序号。以空格作为分隔。

【样例输入1】

6 5

1 2 3 4 5 6

【样例输出1】

5 4 6 2 3 1

【样例输入2】

3 3

3 2 1

【样例输出2】

1 3 2

3.6 顺序表-循环左移
#include  <stdio.h>
#include  <stdlib.h>
#include  <malloc.h>

#define  INIT_SIZE  100
#define  INCREM  10
#define  OK  1
#define  ERROR  0
#define  Swap(a,b)  a  ^=b,b  ^=a,a  ^=b;

typedef  int  ElemType;
typedef  struct  SqList{
        ElemType  *slist;
        int  length;
        int  listsize;
}SqList;
/*传值    传地址*/
int  ListInit_sq(SqList  *L)
{
        L->slist=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
        if(L->slist==NULL)  return  ERROR;
        L->length=0;
        L->listsize=INIT_SIZE;
        return  OK;
}

int  ListInsert_sq(SqList  *L,int  i,ElemType  e)
{
        int  j;
        if(i<1||i>L->length+1)  return  ERROR;
        if(L->length>=L->listsize)
        {
                L->slist=(ElemType*)realloc(L->slist,(L->listsize+INCREM)
                                                                        *sizeof(ElemType));
                if(!L->slist)  return  ERROR;
                L->listsize+=INCREM;
        }
        for(j=L->length;j>=i;j--)
                L->slist[j]=L->slist[j-1];
        L->slist[j]=e;
        L->length++;
        return  OK;
}

int  ListCreateN_sq(SqList  *L,int  n)
{
        int  i;
        ElemType  e;
        for(i=0;i<n;i++)
        {
                scanf("%d",&e);
                ListInsert_sq(L,i+1,e);
        }
        return  OK;
}

void  ListPrint_sq(SqList  *L)
{
        int  i;
        for(i=0;i<L->length;i++)
                printf("%d  ",L->slist[i]);
        printf("\n");
        return;
}
/*程序中如果需要另外定义函数可在此处定义*/

/*将顺序表L中的元素循环左移m位*/
************************************************
void  LeftShift(SqList  *L,int  m)
{
        
for(int i=0;i<L->length+L->length-m;i++){
        ListInsert_sq(L,1,L->slist[L->length-1]);
        L->length--;
    }
}
***************************************************
int  main()
{
        SqList  la;
        int  n,m;
        scanf("%d  %d",&n,&m);
        ListInit_sq(&la);
        ListCreateN_sq(&la,n);
        /*调用函数将顺序表la中元素左移m位*/
      
 LeftShift(&la,m);

    ListPrint_sq(&la);
        return  0;
}
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void createList(LinkList *L,int n)
{
    LinkList p,q;
    p=*L=(LinkList)malloc(sizeof(LNode));
    for(int i=0;i<n;i++){
        q=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&q->data);
        p->next=q;
        p=q;
    }
    p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
//查找+交换
void exchangeList(LinkList L,int x)
{
    LinkList p,q;
    int temp;
    for(p=L;p&&p->data!=x;p=p->next);
    q=p->next;
    temp=p->data;
    p->data=q->data;
    q->data=temp;
}
int main()
{
    LinkList L;
    int n,x;
    scanf("%d",&n);
    createList(&L,n);
    scanf("%d",&x);
    exchangeList(L,x);
    printList(L);
}

3 单链表-考试题库

3.1单链表-插入最大前

在带头结点单链表中查找最大值,将新输入的值插入到最大值前面,输出插入新元素后的单链表各元素。

【输入形式】

第一行输入若干个整数,以字母结束输入,建立带头结点的单链表;

第二行输入待插入的元素值。

【输出形式】

输出插入新值后的单链表各元素。

【样例输入1】

10 8 2 1 6 7 40 a

22

【样例输出1】

10 8 2 1 6 7 22 40

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void  createListLoop(LinkList  *L)
{
        LinkList  p,q;
        ElemType  e;
        p=*L=(LinkList)malloc(sizeof(LNode));
        while(scanf("%d",&e)==1)
        {
                q=(LinkList)malloc(sizeof(LNode));
                q->data=e;
                p->next=q;
                p=q;
         }
        p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
//插入最大前
void insertMax(LinkList L,ElemType e)
{
    LinkList p,q;
    int max,temp;
    for(p=L->next,max=p->data;p;p=p->next)
        if(p->data>max)max=p->data;
    for(p=L;p&&p->data!=max;p=p->next);
    q=(LinkList)malloc(sizeof(LNode));
    q->data=e;
    q->next=p->next;
    p->next=q;
    temp=p->data;
    p->data=q->data;
    q->data=temp;
}
int main()
{
    LinkList L;
    int e;
    createListLoop(&L);
    //吃掉换行空格!
    getchar();
    scanf("%d",&e);
    insertMax(L,e);
    printList(L);
}

3.2单链表-删除重复

按下图所示:

(1)创建包含头结点的单链表,表中的元素是非负整数。

(2)依次输出该链表中的元素

(3)去掉链表中重复的元素,保留元素第一次出现所在的结点。

(4)依次输出去重后该链表中的元素

【输入形式】

一组非负且非递减的整数,以-1结束,整数间以空格隔开
【输出形式】

输出未去重链表中的每个元素,元素间以逗号分隔,输出结束后换行

输出去重后链表中的每个元素,元素间以逗号分隔,输出结束后换行

【样例输入】

13 23 23 23 35 -1
【样例输出】

13,23,23,23,35

13,23,35

【样例输入】

13 13 12 12 -1
【样例输出】

13,13,12,12

13,12

【样例输入】

13 12 11 11 -1
【样例输出】

13,12,11,11

13,12,11

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;
void  createList(LinkList  *L)
{
        LinkList  p,q;
        ElemType  e;
        p=*L=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&e);
        while(e!=-1)
        {
                q=(LinkList)malloc(sizeof(LNode));
                q->data=e;
                p->next=q;
                p=q;
                scanf("%d",&e);
         }
        p->next=NULL;
}
void delRepeat(LinkList L){
    LinkList p,q,r;
    for(p=L;p;p=p->next){
        for(q=p;q->next;){
            if(p->data==q->next->data){
                r=q->next;
                q->next=r->next;
                free(r);
            }
            else
                q=q->next;
        }
    }
}
void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
int main()
{
    LinkList L;
    createList(&L);
    printList(L);
    printf("\n");
    delRepeat(L);
    printList(L);
}

void delRepeat(LinkList L){

LinkList p,q,r;

for(p=L;p;p=p->next){

for(q=p;q->next;){

if(p->data==q->next->data){

r=q->next;

p->next=r->next;

free®;

}

else

q=q->next;

}

}

}

3.3单链表-删除倒数k

设有头结点单链表,删除单链表中倒数第k个结点。

【输入形式】

第一行重复输入整数建立带头结点的单链表,输入字符结束。

第二行输入一个整数k,表示删除倒数第k个结点。

【输出形式】

输出删除后单链表的所有元素

【样例输入1】

10 20 30 40 50 e

3

【样例输出1】

10 20 40 50

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void  createListLoop(LinkList  *L)
{
        LinkList  p,q;
        ElemType  e;
        p=*L=(LinkList)malloc(sizeof(LNode));
        while(scanf("%d",&e)==1)
        {
                q=(LinkList)malloc(sizeof(LNode));
                q->data=e;
                p->next=q;
                p=q;
         }
        p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
//删除倒数k
void deleteLastK(LinkList L,int k)
{
    LinkList p,q;
    int n,j;
    for(p=L->next,n=0;p;p=p->next,n++);
    for(p=L,j=0;p&&j!=n-k;p=p->next,j++);
    if(j!=n-k) return 0;
    q=p->next;
    p->next=q->next;
    free(q);

}
int main()
{
    LinkList L;
    int k;
    createListLoop(&L);
    //吃掉换行空格!
    getchar();
    scanf("%d",&k);
    deleteLastK(L,k);
    printList(L);
}

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void  createListLoop(LinkList  *L)
{
        LinkList  p,q;
        ElemType  e;
        p=*L=(LinkList)malloc(sizeof(LNode));
        while(scanf("%d",&e)==1)
        {
                q=(LinkList)malloc(sizeof(LNode));
                q->data=e;
                p->next=q;
                p=q;
         }
        p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
//删除倒数k
void deleteLastK(LinkList L,int k)
{
    LinkList p,q;
    int n,j;
    for(p=L->next,n=0;p;p=p->next,n++);
    for(p=L,j=0;p&&j!=n-k;p=p->next,j++);
    if(j!=n-k) return 0;
    q=p->next;
    p->next=q->next;
    free(q);

}
int main()
{
    LinkList L;
    int k;
    createListLoop(&L);
    //吃掉换行空格!
    getchar();
    scanf("%d",&k);
    deleteLastK(L,k);
    printList(L);
}

3.4单链表-删除小于k

【问题描述】有整数构成的带头结点单链表,根据输入的x值,删除表中元素值小于x的所有元素,输出删除后的单链表元素。

【输入形式】

第一行输入整数n,表示顺序表中有n个元素;

第二行输入n个整数建立带头结点单链表;

第三行输入x,用于删除表中小于x的元素 ;
【输出形式】

输出删除后的表内元素
【样例输入】

6

2 9 5 7 1 6

5
【样例输出】

9 5 7 6

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void createList(LinkList *L,int n)
{
    LinkList p,q;
    p=*L=(LinkList)malloc(sizeof(LNode));
    for(int i=0;i<n;i++){
        q=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&q->data);
        p->next=q;
        p=q;
    }
    p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}

void  deleteListLessThanX(LinkList  L,ElemType  x)
{
    LinkList p,q,pre;
    for(pre=L,p=L->next;p;)
    {
        if(p->data<x){
            q=p;
            p=p->next;
            pre->next=p;
            free(q);
        }
        else{
            pre=p;
            p=p->next;
        }
    }

}
int main()
{
    LinkList L;
    int x,n;
    scanf("%d",&n);
    createList(&L,n);
    scanf("%d",&x);
    deleteListLessThanX(L,x);
    printList(L);
}

3.5单链表-字符统计⭐

【问题描述】单链表实现字符统计。

【输入形式】从键盘输入N个字符,字符以逗号隔开。
【输出形式】统计各字符出现的次数,并删除重复字符。
【样例输入】5,a,b,c,a,b
【样例输出】

a 2

b 2

c 2

//字符统计
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef char ElemType;
typedef struct LNode
{
    ElemType data;//数据域
    struct LNode *next;//指针域
    int count;
}LNode,*LinkList;

int judgeRepeat(LinkList L,char ch)
{
    LinkList p;
    for(p=L;p;p=p->next){
        if(p->data==ch){
            p->count++;return 1;
        }
    }
    return 0;
}
void createList(LinkList *L)
{
   LinkList p,q;
   int i,n;
   char ch;
   scanf("%d",&n);getchar();
   for(i=0;i<n;i++)
   {
       q=(LinkList)malloc(sizeof(LNode));
       q->count=1;
       q->next=NULL;
       if(i==0) *L=q;
       else p->next=q;
       scanf("%c",&ch);getchar();
       if(judgeRepeat(*L,ch)==1)
            p->next=NULL;
       else{
            q->data=ch;
            p=q;
       }
   }

}

void printList(LinkList L)
{
    LinkList p;
    for(p=L;p;p=p->next)
        printf("%c %d\n",p->data,p->count);
}
int main()
{
    LinkList L;
    createList(&L);
    printList(L);
}

3.6 单链表-按奇偶位序改造带头结点的单链表

设带头结点的单链表表示的线性表L=(a1,a2,a3,a4,……,an),试用复杂度为O(n)的算法,原地将L改造为L=(a1,a3, ……,a2,a4, ……)。

【输入形式】

第一行输入单链表元素个数n;

第二行输入n个整数。

【输出形式】

输出改造后的单链表。

【样例输入】

9

1 2 3 4 5 6 7 8 9

【样例输出】

1 3 5 7 9 2 4 6 8

#include    <stdio.h>
#include    <stdlib.h>
#include<malloc.h>

#define    ERROR    0
#define    OK    1
typedef    int    ElemType;
typedef    struct    LNode
{
        ElemType    data;
        struct    LNode    *next;
}  LNode,*LinkList;

void    CreateListTail(LinkList    *L,int    n)
{
        LinkList    p,q;
        int    i;
        int    e;
        (*L)=p=(LinkList)malloc(sizeof(LNode));
        for(i=1;  i<=n;  i++)
        {
                q=(LinkList)malloc(sizeof(LNode));
                scanf("%d",&e);
                q->data=e;
                p->next=q;
                p=q;
        }
        p->next=NULL;
}

void    PrintList(LinkList    L)
{
        LinkList    p=L->next;
        while(p!=NULL)
        {
                printf("%d  ",p->data);
                p=p->next;
        }
        printf("\n");
}

void    OEReform(LinkList    L)
{
    LinkList r, p, oldEnd;  //链表最后一个结点, 链表结点的替代结点
  int flag=0;
  r = L->next;
  p = L;
  // r定位到链表的最后一个结点
  while(r->next){
    r = r->next;
  }
  oldEnd = r;
  while(p->next!=oldEnd || (p->next==oldEnd&&p->next->data&1==0)){
    if(p->next->data%2==0){
      if(p->next==oldEnd)
        flag = 1;
      //把偶数结点接到表尾
      r->next = p->next;
      r = r->next;

      //跳过偶数结点
      p->next = p->next->next;

      //单独处理最后一个偶数结点的情况
      if(flag){
        break;
      }
    }else{
      p = p->next;
    }
  }
  r->next = NULL;

}

int    main()
{
        LinkList    L;
        int    n;
        scanf("%d",&n);
        CreateListTail(&L,n);
        OEReform(L);
        PrintList(L);
        return    0;
}

3.7单链表-单向变双向

假设一个双向循环链表,其结点含有三个域:prior,data和next。其中data为数据域;prior指向前驱结点,next指向后继结点。创建链表时,只链接了next域,导致链表只是一个单向循环链表。请补充算法,修复双向链表,可以实现双向访问。

【输入形式】

第1行输入n,表示输入n个数据。

第2行输入n个整数,创建循环链表。(只创建了单向)

【输出形式】

从头到尾输出链表元素;

从尾到头输出链表元素;

【样例输入】

5

1 2 3 4 5

【样例输出】

1 2 3 4 5

5 4 3 2 1

#include <stdio.h>
#include <stdlib.h>
typedef  int ElemType;
typedef  struct  DuLNode{
      ElemType  data;
      struct DuLNode  *next;
      struct DuLNode  *prior;
}DuLNode,*DuLinkList;

void createList(DuLinkList *h,DuLinkList *r)
{
    DuLinkList p,q;
    int i,n;
    scanf("%d",&n);
    p=*h=(DuLinkList)malloc(sizeof(DuLNode));
    if(!p) return 0;
    p->prior=NULL;
    for(i=0;i<n;i++){
        q=(DuLinkList)malloc(sizeof(DuLNode));
        scanf("%d",&q->data);
        q->prior=p;
        p->next=q;
        p=q;
    }
    p->next=NULL;
    *r=p;
}

//单向变双向
int DoubleLinks(DuLinkList h)
{
    DuLinkList p,q;
    for(p=L,q=p->next;p!=h;p=q,q=p->next)
        q->prior=p;
    
}
void printList(DuLinkList h,DuLinkList r)
{
    DuLinkList p;
    for(p=h->next;p;p=p->next)
        printf("%d ",p->data);
    printf("\n");
    for(p=r;p->prior;p=p->prior)
        printf("%d ",p->data);

}

int main()
{
    DuLinkList h,r;
    createList(&h,&r);
    printList(h,r);
}

3.8单链表-删除区间

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void createList(LinkList *L,int n)
{
    LinkList p,q;
    p=*L=(LinkList)malloc(sizeof(LNode));
    for(int i=0;i<n;i++){
        q=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&q->data);
        p->next=q;
        p=q;
    }
    p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
//删除(x,y)内的元素
int deleteList(LinkList L,int x,int y)
{
    LinkList p,pre;
    for(pre=L,p=L->next;p;){
        if(p->data>x&&p->data<y){
            pre->next=p->next;
            free(p);
            p=pre->next;
        }
        else{
            pre=p;
            p=p->next;
         }
    }
}
int main()
{
    LinkList L;
    int n,x,y,e;
    scanf("%d",&n);
    createList(&L,n);
    scanf("%d%d",&x,&y);
    deleteList(L,x,y);
    printList(L);
}

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void createList(LinkList *L,int n)
{
    LinkList p,q;
    p=*L=(LinkList)malloc(sizeof(LNode));
    for(int i=0;i<n;i++){
        q=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&q->data);
        p->next=q;
        p=q;
    }
    p->next=NULL;
}

void printList(LinkList L)
{
    LinkList p;
    for(p=L->next;p;p=p->next)
        printf("%d ",p->data);
}
//删除(x,y)内的元素
int deleteList(LinkList L,int x,int y)
{
    LinkList p,pre;
    for(pre=L,p=L->next;p;){
        if(p->data>x&&p->data<y){
            pre->next=p->next;
            free(p);
            p=pre->next;
        }
        else{
            pre=p;
            p=p->next;
         }
    }
}
int main()
{
    LinkList L;
    int n,x,y,e;
    scanf("%d",&n);
    createList(&L,n);
    scanf("%d%d",&x,&y);
    deleteList(L,x,y);
    printList(L);
}

4 循环链表

4.1 循环链表-合并

【问题描述】根据输入新建两个用尾指针标识的单循环链表,利用原有结点合并两个单循环链表,用尾指针返回合并后的循环单链表。
【输入形式】第一行输入若干个整数(以字符结束输入)构建第一个单循环链表,第二行输入若干个整数(以字符结束输入)构建第二个循环单链表。
【输出形式】输出合并后的循环单链表。
【样例输入】

1 2 3 4 5a

7 8 9a
【样例输出】

1 2 3 4 5 7 8 9

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

//创建尾指针的循环链表
LinkList  createListRear()
{
   LinkList h,p,q;
   p=h=(LinkList)malloc(sizeof(LNode));
   ElemType e;
   while(scanf("%d",&e)==1)
   {
       q=(LinkList)malloc(sizeof(LNode));
       q->data=e;
       p->next=q;
       p=q;
   }
   p->next=h;
   return p;
}
//输出
void printList(LinkList r)
{
   LinkList p;
   for(p=r->next->next;p!=r->next;p=p->next)
        printf("%d ",p->data);
}
//链表的合并
void linkList(LinkList r1,LinkList r2)
{
    LinkList p,q;
    p=r1->next;
    q=r2->next;
    r1->next=q->next;
    r2->next=p;
    free(q);

}
int main()
{
    LinkList a,b;
    a=createListRear();
    getchar();
    b=createListRear();
    linkList(a,b);
    printList(b);
}

4.2 循环链表-约瑟夫⭐

约瑟夫环问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀的顺序是:5,4,6,2,3,1。

【输入形式】

输入两个正整数N和M,N表示N个人,M表示报数到M;

【输出形式】

输出依次出列的序号。以空格作为分隔。

【样例输入1】

6 5

1 2 3 4 5 6

【样例输出1】

5 4 6 2 3 1

【样例输入2】

3 3

3 2 1

【样例输出2】

1 3 2

#include<malloc.h>
#include<stdio.h>
#include<stdlib.h>

#define ERROR 0//操作返回值
#define OK 1

typedef int ElemType;
typedef struct LNode{
    ElemType data;
    struct LNode *next;
    }LNode,*LinkList;

LinkList CreateLoopListN(int n)
{
    int i;
    LinkList head,p,s;
    p=head=(LinkList)malloc(sizeof(LNode));
    //if(!p) return p;
    scanf("%d",&(head->data));
    for(i=2;i<=n;i++)
    {
        s=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&(s->data));
        p->next=s;
        p=s;
    }
    p->next=head;
    return p;
}

void PrintLoopListRear(LinkList rear)
{
    LinkList p;
    if( rear==NULL) return;
    p=rear->next;
    printf("%d ",p->data);
    p=p->next;
    while(p!=rear->next)
    {
         printf("%d ",p->data);
         p=p->next;
    }
    printf("\n");
}

void Josephus(LinkList rear,int n,int m)
{
    LinkList p,q;
        int c=1;
        if(rear==NULL)rear;
        q=rear;
        p=rear->next;
        while(q!=p)
        {
        if(c==m)
        {
            q->next=p->next;
            printf("%d ",p->data);
            free(p);
            p=q->next;
            c=1;
        }
        else{
            c++;
            p=p->next;
            q=q->next;
        }}
        printf("%d ",p->data);
        free(p);
}

int main()
{
    LinkList rear;
    int n,m;
    scanf("%d %d",&n,&m);
    rear=CreateLoopListN(n);
   // PrintLoopListRear(rear);
    Josephus(rear,n,m);
    return 1;
}

3栈-考试题库

3.1出栈序列

给出一个堆栈的输入序列,试判断一个输出序列是否能够由这个堆栈输出。如果能输出yes,如果不能,输出no。

序列的输入及输出都是从左往右。(输入输出序列皆为整数且没有重复的数字,如果一个数字在输入序列中没有出现,那么其在输出序列中也不会出现)

【输入形式】

第一行为输入序列的长度,其后依次为输入序列的数字;

第二行为输出序列的数字。

输入数据以空格隔开。

【输出形式】

输出总共的出栈次数,如果是一个正确的出栈序列,则输出yes, 否则输出no。

【样例输入1】

5 1 2 3 4 5

4 5 3 2 1

【样例输出1】

5

yes

【样例说明1】可以按以下顺序执行:

push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

通过5次pop操作可以得到输出序列,因此返回5

【样例输入2】

5 1 2 3 4 5

4 3 5 1 2

【样例输出2】

3

no

【样例说明2】1不能在2之前输出,因此输出no。

口诀:for+2while

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define ERROR 0
#define OK 1
#define INIT_SIZE 100
#define INCREMENT 50

typedef int ElemType;
typedef struct SqStack{
    ElemType *base,*top;
    int stacksize;
}SqStack;
/*初始化顺序栈*/
int InitStack(SqStack *s)
{
   s->base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
   if(!s->base) return 0;
   s->top=s->base;
   s->stacksize=INCREMENT;
   return 1;

}
/*判栈空*/
int Empty(SqStack *s)
{
    if(s->base==s->top) return 1;
    else return 0;

}
/*入栈*/
int Push(SqStack *s,ElemType e)
{
    if(s->top-s->base>=s->stacksize){
        s->base=(ElemType*)realloc(s->base,(s->stacksize+INCREMENT)*sizeof(ElemType));
        if(!s->base) return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=INCREMENT;
    }
    *s->top++=e;
    return 1;

}
/*出栈*/
int Pop(SqStack *s,ElemType *e)
{
    if(s->base==s->top) return 0;
    *e=*--s->top;
    return 1;

}
/*取栈顶元素*/
int GetTop(SqStack *s,ElemType *e)
{
   if(s->top==s->base) return 0;
   *e=*(s->top-1);
   return 1;

}

int main()
{
    SqStack s;
    ElemType e;
    InitStack(&s);
    int in[100]; //输入序列
    int out[100];//输出序列

/*此处填充代码,利用堆栈基本操作判断序列是否为正确的出栈序列*/
    int i,j,n;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&in[i]);
    for(i=0;i<n;i++)
        scanf("%d",&out[i]);
    for(i=0,j=0;i<n&&j<n;)
    {
        while((Empty(&s)==1)||GetTop(&s,&e)==1&&e!=out[j])
            Push(&s,in[i++]);
        while(GetTop(&s,&e)==1&&e==out[j]){
            Pop(&s,&e);
            j++;
        }
    }
    if(Empty(&s)==1){
        printf("%d\n",j);
        printf("yes");
    }
    else{
        printf("%d\n",j);
        printf("no");
    }
}
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define ERROR 0
#define OK 1
#define INIT_SIZE 100
#define INCREMENT 50

typedef int ElemType;
typedef struct SqStack{
    ElemType *base,*top;
    int stacksize;
}SqStack;
/*初始化顺序栈*/
int InitStack(SqStack *s)
{
   s->base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
   if(!s->base) return 0;
   s->top=s->base;
   s->stacksize=INCREMENT;
   return 1;

}
/*判栈空*/
int Empty(SqStack *s)
{
    if(s->base==s->top) return 1;
    else return 0;

}
/*入栈*/
int Push(SqStack *s,ElemType e)
{
    if(s->top-s->base>=s->stacksize){
        s->base=(ElemType*)realloc(s->base,(s->stacksize+INCREMENT)*sizeof(ElemType));
        if(!s->base) return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=INCREMENT;
    }
    *s->top++=e;
    return 1;

}
/*出栈*/
int Pop(SqStack *s,ElemType *e)
{
    if(s->base==s->top) return 0;
    *e=*--s->top;
    return 1;

}
/*取栈顶元素*/
int GetTop(SqStack *s,ElemType *e)
{
   if(s->top==s->base) return 0;
   *e=*(s->top-1);
   return 1;

}

int main()
{
    SqStack s;
    ElemType e;
    InitStack(&s);
    int in[100]; //输入序列
    int out[100];//输出序列

/*此处填充代码,利用堆栈基本操作判断序列是否为正确的出栈序列*/
    int i,j,n;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&in[i]);
    for(i=0;i<n;i++)
        scanf("%d",&out[i]);
    for(i=0,j=0;i<n&&j<n;)
    {
        while((Empty(&s)==1)||GetTop(&s,&e)==1&&e!=out[j])
            Push(&s,in[i++]);
        while(GetTop(&s,&e)==1&&e==out[j]){
            Pop(&s,&e);
            j++;
        }
    }
    if(Empty(&s)==1){
        printf("%d\n",j);
        printf("yes");
    }
    else{
        printf("%d\n",j);
        printf("no");
    }
}

3.2传纸条

多次在信息的任意位置随意的添加两个相同的字母;最后再将信息内容逆置

【输入形式】

输入数据的第一行为一个正整数 T(T ≤ 30),表示共有 T 组测试数据。

接下来 T 行,每行为一个字符串,字符串仅包含小写英文字母,且保证原始字符串中不包含相邻两个相同的字母,字符串长度不超过2000。

【输出形式】

每组数据输出一行字符串,表示还原后的内容。

【样例输入】

1

uuuevfaafoliss

【样例输出】

iloveu

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define ERROR 0
#define OK 1
#define STACK_INT_SIZE 1000
#define STACKINCREMENT 50
typedef  char ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stacksize;
} SqStack;

int initStack(SqStack *s);
int emptyStack(SqStack *s);
int pushStack(SqStack *s, ElemType e);
int popStack(SqStack *s,ElemType *e);
int getTop(SqStack *S,ElemType *e);

int initStack(SqStack *s)
{
    s->base=(ElemType *)malloc(STACK_INT_SIZE*sizeof(ElemType));
    if(!s->base)
        return ERROR;
    s->top=s->base;
    s->stacksize=STACK_INT_SIZE;
    return OK;
}

int emptyStack(SqStack *s)
{
    if(s->top==s->base)
        return OK;
    else
        return ERROR;
}

int pushStack(SqStack *s, ElemType e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(ElemType *)realloc(s->base,(STACKINCREMENT+s->stacksize)*sizeof(SqStack));
        if(!s->base)
            return ERROR;
        s->top=s->base+s->stacksize;
        s->stacksize+=STACKINCREMENT;
    }
    *s->top=e;
    s->top++;
    return OK;
}

int popStack(SqStack *s,ElemType *e)
{
    if(emptyStack(s))
        return ERROR;
    *e=*--s->top;
    return OK;
}
int getTop(SqStack *S,ElemType *e)
{
    if(S->top==S->base)
        return ERROR;
    *e=*(S->top-1);
    return OK;
}
//补充函数,实现纸条解密
int decrypt(char *note,char *original)
{
    SqStack s;
    initStack(&s);
    int i,j;
    ElemType e;
    for(i=0;note[i]!='\0';i++){
        if(getTop(&s,&e)&&e==note[i])
            popStack(&s,&e);
        else
            pushStack(&s,note[i]);
    }
    j=0;
    while(popStack(&s,&e)==1)
        original[j++]=e;
    original[j]='\0';
}
int main()
{
    int n;
    char note[2000],original[2000];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",note);
        original[0]='\0';
        if(decrypt(note,original))
            printf("%s\n",original);
    }
    return 0;
}

2-2括弧匹配

利用栈的基本操作,完成表达式括弧匹配的检测。(假设表达式中只有()、[]、{}三类括弧)

【输入形式】

输入若干个表达式(字符串形式)。(提示:使用scanf(“%s”,a)==1)

【输出形式】

若表达式括弧匹配,则输出“match”;否则输出"not match"

【样例输入】

1 *(3+4)/4

((3+4)*7-(8-9)

*

((1+2)(3_4)-(5+6)*3)

{}

【样例输出】

match

not match

match

not match

#include<stdio.h>
#include<stdlib.h>

int judge(char *ch)
{
    int top=0,base=0;
    char b[100];
    for(int i=0;ch[i]!='\0';i++){
        if(ch[i]=='('||ch[i]=='['||ch[i]=='{')
            b[top++]=ch[i];
        if(ch[i]==')'){
            if((b[top-1]=='(')&&top!=base)
                top--;
            else return 0;
        }
        if(ch[i]==']'){
            if((b[top-1]=='[')&&top!=base)
                top--;
            else return 0;
        }
        if(ch[i]=='}'){
            if((b[top-1]=='{')&&top!=base)
                top--;
            else return 0;
        }
    }
    if(top==base) return 1;
        else return 0;
}

int main()
{
    char ch[100];
    while(scanf("%s",ch)==1)
        printf(judge(ch)?"match\n":"not match\n");
}

第二种方法有一组数据不对

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define INIT_SIZE 100
#define INCREAM 50
#define MAX 100

typedef int ElemType;
typedef struct
{
    ElemType *top;//栈顶
    ElemType *base;//栈底
    int stacksize;//容量
}SqStack,*Stack;//线性栈
//创建栈
int createStack(Stack s)
{
    s->base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
    if(!s->base) return 0;
    s->top=s->base;
    s->stacksize=INIT_SIZE;
    return 1;
}
//入栈
int push(Stack s,ElemType e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(ElemType*)realloc(s->base,(s->stacksize+INCREAM)*sizeof(ElemType));
        if(!s->base) return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=INCREAM;
    }
    *s->top++=e;
    return 1;
}
//出栈
int pop(Stack s,ElemType *e)
{
    if(s->top==s->base) return 0;
    *e=*--s->top; return 1;
}

//括弧匹配
int match(Stack s,char* str)
{
    int i;
    ElemType e;
    for(i=0;str[i]!='\0';i++){
        if(str[i]=='('||str[i]=='['||str[i]=='{')
            push(s,str[i]);
        if(str[i]==')'){
            if(!pop(s,&e)) return 0;
                if(e!=')') return 0;
            }
        if(str[i]==']'){
            if(!pop(s,&e)) return 0;
                if(e!='[') return 0;
            }
        if(str[i]=='}'){
            if(!pop(s,&e)) return 0;
                if(e!='{') return 0;
            }
    }
    if(s->top==s->base) return 1;
    else return 0;
}
int main()
{
    SqStack S;
    Stack s=&S;
    char str[MAX];
    createStack(s);
    while(scanf("%s",str)==1)
        printf(match(s,str)?"match\n":"not match\n");
}

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define INIT_SIZE 100
#define INCREAM 50
#define MAX 100

typedef int ElemType;
typedef struct
{
    ElemType *top;//栈顶
    ElemType *base;//栈底
    int stacksize;//容量
}SqStack,*Stack;//线性栈
//创建栈
int createStack(Stack s)
{
    s->base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
    if(!s->base) return 0;
    s->top=s->base;
    s->stacksize=INIT_SIZE;
    return 1;
}
//入栈
int push(Stack s,ElemType e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(ElemType*)realloc(s->base,(s->stacksize+INCREAM)*sizeof(ElemType));
        if(!s->base) return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=INCREAM;
    }
    *s->top++=e;
    return 1;
}
//出栈
int pop(Stack s,ElemType *e)
{
    if(s->top==s->base) return 0;
    *e=*--s->top; return 1;
}

//括弧匹配
int match(Stack s,char* str)
{
    int i;
    ElemType e;
    for(i=0;str[i]!='\0';i++){
        if(str[i]=='('||str[i]=='['||str[i]=='{')
            push(s,str[i]);
        if(str[i]==')'){
            if(!pop(s,&e)) return 0;
                if(e!=')') return 0;
            }
        if(str[i]==']'){
            if(!pop(s,&e)) return 0;
                if(e!='[') return 0;
            }
        if(str[i]=='}'){
            if(!pop(s,&e)) return 0;
                if(e!='{') return 0;
            }
    }
    if(s->top==s->base) return 1;
    else return 0;
}
int main()
{
    SqStack S;
    Stack s=&S;
    char str[MAX];
    createStack(s);
    while(scanf("%s",str)==1)
        printf(match(s,str)?"match\n":"not match\n");
}

2-3进制转换

利用栈实现十进制向二进制的转换。

【输入形式】

输入若干个十进制正整数,输出它们的二进制形式。(提示:输入采用scanf(“%d”,&x)==1)

【输出形式】

输出每个十进制正整数的二进制形式。
【样例输入】

5

7

20

255

128

127

1000

50000

65535

【样例输出】

101

111

10100

11111111

10000000

1111111

1111101000

1100001101010000

1111111111111111

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define INIT_SIZE 10
#define INCREAM 5

typedef int ElemType;
typedef struct
{
    ElemType *top;//栈顶
    ElemType *base;//栈底
    int stacksize;//容量
}SqStack,*Stack;//线性栈
//创建栈
int createStack(Stack s)
{
    s->base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
    if(!s->base) return 0;
    s->top=s->base;
    s->stacksize=INIT_SIZE;
    return 1;
}
//入栈
int push(Stack s,ElemType e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(ElemType*)realloc(s->base,(s->stacksize+INCREAM)*sizeof(ElemType));
        if(!s->base) return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=INCREAM;
    }
    *s->top++=e;
    return 1;
}
//出栈
int pop(Stack s,ElemType *e)
{
    if(s->top==s->base) return 0;
    *e=*--s->top; return 1;
}

int conversion(Stack s,int x)
{
    ElemType e;
    if(x==0){
        printf("0");return 0;
    }
    while(x){
        push(s,x%2);
        x/=2;
    }
    while(s->top!=s->base){
        pop(s,&e);
        printf("%d",e);
    }
}
int main()
{
    SqStack S;
    Stack s=&S;
    int x;
    createStack(s);
    while(scanf("%d",&x)==1){
        conversion(s,x);
        printf("\n");
    }
}

十六进制+x

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define INIT_SIZE 10
#define INCREAM 5

typedef int ElemType;
typedef struct
{
    ElemType *top;//栈顶
    ElemType *base;//栈底
    int stacksize;//容量
}SqStack,*Stack;//线性栈
//创建栈
int createStack(Stack s)
{
    s->base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
    if(!s->base) return 0;
    s->top=s->base;
    s->stacksize=INIT_SIZE;
    return 1;
}
//入栈
int push(Stack s,ElemType e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(ElemType*)realloc(s->base,(s->stacksize+INCREAM)*sizeof(ElemType));
        if(!s->base) return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=INCREAM;
    }
    *s->top++=e;
    return 1;
}
//出栈
int pop(Stack s,ElemType *e)
{
    if(s->top==s->base) return 0;
    *e=*--s->top; return 1;
}

int conversion(Stack s,int x)
{
    ElemType e;
    if(x==0){
        printf("0");return 0;
    }
    while(x){
        push(s,x%16);
        x/=16;
    }
    while(s->top!=s->base){
        pop(s,&e);
        printf("%X",e);
    }
}
int main()
{
    SqStack S;
    Stack s=&S;
    int x;
    createStack(s);
    while(scanf("%d",&x)==1){
        conversion(s,x);
        printf("\n");
    }
}

2-4后缀表达式

设计一个程序,实现简单整数的四则运算(运算对象不小于0),包括加减乘除和小括号。

【输入形式】

每行输入一个运算表达式(假设表达式均为正确的表达式),以#作为表达式结束。(表达式长度不超过80)

【输出形式】

输出表达式的后缀式

输出运算结果

【样例输入】

23-(2-4)*2+36/(20-14)#

*

(100-23)/6+2(13-9)-40#

((100-20)*2)-35#

120+30+50#

【样例输出】

23 2 4 - 2 * - 36 20 14 - / +

33
100 23 - 6 / 2 13 9 - * + 40 -

-20

100 20 - 2 * 35 -

125
120 30 + 50 +

200

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
int main()
{
    char a[100];
    char b[200];
    char c[100];
    int i,j,t;
    while(scanf("%s",a)==1){
    j=0;t=-1;
    for(i=0;a[i]!='#';i++)
    {
       switch(a[i]){
        case'(':
            t++;
            c[t]=a[i];
            break;
        case')':
            while(c[t]!='('){
                b[j]=c[t];j++;t--;
                b[j]=' ';j++;
            }
            t--;
            break;
        case'+':
        case'-':
            while(t!=-1&&c[t]!='('){
                b[j]=c[t];j++;t--;
                b[j]=' ';j++;
            }
            t++;
            c[t]=a[i];
            break;
        case'*':
        case'/':
            while(c[t]=='*'||c[t]=='/'){
                b[j]=c[t];j++;t--;
                b[j]=' ';j++;
            }
            t++;
            c[t]=a[i];
            break;
        default:
            while(isdigit(a[i])){
                b[j]=a[i];i++;j++;
            }
            i--;b[j]=' ';j++;
        }

    }
    while(t!=-1){
        b[j]=c[t];j++;t--;
        b[j]=' ';j++;
    }
    puts(b);
    }
}

后缀表达式计算
#include  <stdio.h>
#include  <stdlib.h>

int  main() {
    char s1[100];//s1存放中缀表达式
    char s2[200];//s2为后缀表达式
    char s3[100];//s3存放运算符
    int i;
    while (scanf("%s", s1) == 1) {
        i = 0;
        int top = -1;//top指向运算符栈顶元素
        int j = 0;//数组s2下标
        while (s1[i] != '#') {
            switch (s1[i]) {
            case'('://左括号直接入栈
                top++;
                s3[top] = s1[i];
                break;
            case')'://右括号之前直到左括号的运算符出栈
                while (s3[top] != '(') {
                    s2[j] = s3[top];
                    top--;
                    j++;
                    s2[j] = ' ';
                    j++;
                }
                top--;
                break;
            case'+'://+-运算符优先级高于(,只有栈顶非空且非(时入栈,否则出栈
            case'-':
                while (top != -1 && s3[top] != '(') {
                    s2[j] = s3[top];
                    top--;
                    j++;
                    s2[j] = ' ';
                    j++;
                }
                top++;
                s3[top] = s1[i];
                break;
            case'*'://*/运算符优先级高于(+-,只有栈顶也为*或/时入栈,否则出栈
            case'/':
                while (s3[top] == '*' || s3[top] == '/') {
                    s2[j] = s3[top];
                    top--;
                    j++;
                    s2[j] = ' ';
                    j++;
                }
                top++;
                s3[top] = s1[i];
                break;
            default://数字处理
                while (s1[i] >= '0' && s1[i] <= '9') {
                    s2[j] = s1[i];
                    j++;
                    i++;
                }
                i--;
                s2[j] = ' ';
                j++;
            }
            i++;
        }
        while (top != -1) {//将运算符栈中剩余运算符出栈
            s2[j] = s3[top];
            j++;
            top--;
            s2[j] = ' ';
            j++;
        }
        for (i = 0; i < j; i++) {
            printf("%c", s2[i]);
        }

        int s4[100];//s4存放结果
        int shu = 0;
        i = 0, top = -1;//i为s2下标,top为s4下标
        while (s2[i] != ' ' && i != j) {
            switch (s2[i]) {
            case'+':
                s4[top - 1] = s4[top - 1] + s4[top];
                top--;
                i++;
                break;
            case'-':
                s4[top - 1] = s4[top - 1] - s4[top];
                top--;
                i++;
                break;
            case'*':
                s4[top - 1] = s4[top - 1] * s4[top];
                top--;
                i++;
                break;
            case'/':
                s4[top - 1] = s4[top - 1] / s4[top];
                top--;
                i++;
                break;
            default:
                shu = 0;
                while (s2[i] >= '0' && s2[i] <= '9') {
                    shu = 10 * shu + s2[i] - '0';
                    i++;
                }
                top++;
                s4[top] = shu;
            }
            i++;
        }
        printf("\n%d\n", s4[top]);
    }
    return  0;
}

2 队列-考试题库

2.1链队-尾节点

【输入形式】

输入若干个整数(以空格分隔),其中0表示做出队操作,不为0的整数为入队元素。

【输出形式】

若出队错误输出“error”;

若最后队列为空,则输出“empty”;

若最后队列非空,依次输出队列的全部元素。

【样例输入1】

1 2 3 4 5 6
【样例输出1】

1 2 3 4 5 6

【样例输入2】

1 2 3 0 0 4 0 5
【样例输出2】

4 5

【样例输入3】

1 0 2 0 3 0
【样例输出3】

empty

【样例输入4】

1 0 2 0 0 3 0 0 0
【样例输出4】

error

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef int ElemType;

typedef struct QNode{
    ElemType data;
    struct QNode *next;
    }QNode;//队列结点类型定义

typedef struct LinkQueue{
    QNode* rear;
     }LinkQueue;//队列类型定义
/*初始化队列*/
int InitQueue(LinkQueue *q)
{
    q->rear=(QNode*)malloc(sizeof(QNode));
    if(!q->rear) return 0;
    q->rear->next=q->rear;
}
/*入队*/
int EnQueue(LinkQueue *q,ElemType e)
{
    QNode *p=(QNode*)malloc(sizeof(QNode));
    if(!p) return 0;
    p->data=e;
    //
    p->next=q->rear->next;
    q->rear->next=p;
    q->rear=p;
}
/*判断队列是否为空*/
int QueueEmpty(LinkQueue *q)
{
    if(q->rear->next==q->rear) return 1;
    else return 0;
}
/*出队*/
int DeQueue(LinkQueue *q,ElemType *e)
{
    if(QueueEmpty(q)==1) return 0;
    QNode *p;
    //p是尾节点
    p=q->rear->next;
    *e=p->next->data;
    //删除尾节点
    q->rear->next=p->next;
    free(p);
}

int main()
   {
        LinkQueue q;
        ElemType e;
        InitQueue(&q);
        while(scanf("%d",&e)==1)
        {
            if(e)
            {
                EnQueue(&q,e);
            }
            else
            {
                if(QueueEmpty(&q))
                {
                    printf("error");
                    return 0;
                }
                else
                {
                    DeQueue(&q,&e);
                }
            }
        }
        if(QueueEmpty(&q))
            printf("empty");
        else
        {
            while(!QueueEmpty(&q))
            {
                DeQueue(&q,&e);
                printf("%d ",e);
            }
        }
        return 1;
   }

2.2链队-银行AB窗口模拟

【问题描述】设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

【输入形式】第一行输入一个正整数N(≤1000)表示顾客总数,第二行输入n个正整数表示N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,编号为偶数的顾客则去B窗口。数字间以空格分隔。

【输出形式】按业务处理完成的顺序输出顾客的编号。数字间以空格分隔。

【样例输入】

8
2 1 3 9 4 11 13 15

【样例输出】

1 3 2 9 11 4 13 15

#include<stdio.h>
int main()
{
    int a[1001];
    int b[1001];
    int n,t,ca=0,cb=0,k=0,x=1,y=1;
    scanf("%d",&n);
    while(n--){
        scanf("%d",&t);
        if(t%2)
            a[++ca]=t;
        else
            b[++cb]=t;
    }
    while(x<=ca||y<=cb){
        if(x<=ca){
            if(k++)
                printf(" ");
            printf("%d",a[x++]);
        }
        if(x<=ca){
            if(k++)
                printf(" ");
            printf("%d",a[x++]);
        }
        if(y<=cb){
            if(k++)
                printf(" ");
            printf("%d",b[y++]);
        }
    }
}
#include<stdio.h>

#include<malloc.h>

#define ERROR 0

#define OK 1

#define MAXQSIZE 20

typedef  int QElemType; /*队列元素类型*/

typedef struct

{

  QElemType *base;

  int front;

  int rear;

}SqQueue;

/*初始化队列*/

int InitQueue(SqQueue *q)

{

  q->base=(QElemType*)malloc(MAXQSIZE+sizeof(QElemType));

  if(!q->base) return 0;

  q->front=q->rear=0;

}/*InitQueue*/

/*求队长*/

int QueueLength(SqQueue *q)

{

  return (q->rear-q->front+MAXQSIZE)%MAXQSIZE;

}/*QueueLentgh*/

/*入队*/

int EnQueue(SqQueue *q,QElemType e)

{

  if((q->rear+1)%MAXQSIZE==q->front) return 0;

  q->base[q->rear]=e;

  q->rear=(q->rear+1)%MAXQSIZE;

}/*EnQuese*/

/*出队*/

int DeQueue(SqQueue *q,QElemType *e)

{

  if(q->front==q->rear) return 0;

  *e=q->base[q->front];

  q->front=(q->front+1)%MAXQSIZE;

}

/*DeQueue*/

/*判队空*/

int QueueEmpty(SqQueue *q)

{

  if(q->front==q->rear) return 1;

  else return 0;

}/*QueueEmpty*/

/*取队头*/

int GetHead(SqQueue *Q,QElemType *e)

{

  if(Q->front==Q->rear)

    return ERROR;

  *e=Q->base[Q->front];

  return OK;

}/*GetHead*/

/*销毁队列*/

int DestroyQueue(SqQueue *Q)

{

  if(Q->base)

  {

    Q->rear=Q->front=0;

    free(Q->base);

  }

  return OK;

}/*DestroyQueue*/

int main()

{

  SqQueue q;

  int e;

  InitQueue(&q);

/*使用队列基本操作完成程序功能*/

  while(scanf("%d",&e)==1)

  {

    if(e)

    {

      EnQueue(&q,e);

    }else

    {

      if(QueueEmpty(&q))

      {

        printf("error");

        return 0;

      }else

      {

        DeQueue(&q,&e);

      }

    }

  }

  if(QueueLength(&q))

  {

    while(!QueueEmpty(&q))

    {

      DeQueue(&q,&e);

      printf("%d ",e);

    }

  }else

  {

    printf("empty");

  }

  return 0;
  }

3 串-考试题库

3.1模式匹配-BF

串的模式匹配算法BF的实现与应用。

【输入形式】

第一行输入主串s;

第二行输入模式串t;

输入串中均不包含空格字符。

【输出形式】

模式串在主串s中的出现的每一个位置序号。若一次都未匹配到,则输出0。

【样例输入1】

ababcabcacbab

ab

【样例输出1】

1 3 6 12

【样例输入2】

111113455113232342432432

11

【样例输出2】

1 2 3 4 10

【样例输入3】

fasdfdsfsadfdsdsagetgrdgfdgdf

2312

【样例输出3】

0

【评分标准】

使用BF算法。

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define INIT_SIZE 1000
#define INCRE 20
#define OK 1
#define ERROR 0

typedef struct{
  char* data;
  int length,stringsize;
}SqString;

//串初始化
int initString(SqString *s)
{
    s->data=(char*)malloc(INIT_SIZE*sizeof(char));
    if(!s->data) return 0;
    s->length=0;
    s->stringsize=INIT_SIZE;
    return 1;
}

//串赋值
int strAssign(SqString *s, char *str )
{
    int i;
    for(i=0;str[i]!='\0';i++)
        s->data[i]=str[i];
    s->data[i]='\0';
    s->length=i;
    return 1;
}
//基本模式匹配算法
int index_bf(SqString *s,SqString *t,int start)
{
  int i,j=0;
  i=start-1;
  while(i<s->length&&j<t->length)
  {
      if(s->data[i]==t->data[j])
      {
          i++;
          j++;
      }
      else
      {
          i=i-j+1;
          j=0;
      }
  }
    //if(i==2)
        //return i-1;
    //else 
        if(j>=t->length)
        return i-t->length+1;
    else
        return 0;
}
int main(){
     SqString s,t;
     initString(&s);
     initString(&t);
     char str[INIT_SIZE];
     gets(str);
     strAssign(&s,str);
     gets(str);
     strAssign(&t,str);
     int i;
     if(index_bf(&s,&t,1)==0)
       {
           printf("0");return 0;
       }
     for(i=1;index_bf(&s,&t,i)!=0&&i<s.length+t.length;i++){
               i=index_bf(&s,&t,i);
               printf("%d ",i);
           }
}

3.2模式匹配-KMP

串的模式匹配算法实现(KMP算法)

【输入形式】

第一行输入主串s;

第二行输入模式串t;

第三行输入起始位置pos;

【输出形式】

输出模式串t的next值(以空格分隔)

输出模式匹配结果

【样例输入1】

ababcabcacbab

abcac

1

【样例输出1】

-1 0 0 0 1

6

【评分标准】

采用kmp算法。(next值从-1开始)

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

#define INITSIZE 1000
#define INCRE 20
#define OK 1
#define ERROR 0

typedef struct{
  char* data;
  int length,stringsize;
}SqString;

//串初始化
int initString(SqString *s)
{
    s->data=(char*)malloc(INITSIZE*sizeof(char));
    if(!s->data) return 0;
    s->length=0;
    s->stringsize=INITSIZE;
    return 1;
}

//串赋值
int strAssign(SqString *s, char *str )
{
     int i;
    for(i=0;str[i]!='\0';i++)
        s->data[i]=str[i];
    s->data[i]='\0';
    s->length=i;
    return 1;

}
//求取模式串next值
void getNext(SqString *t,int next[])
{
    int i=0,j=-1;
    next[0]=-1;
    while(i<t->length)
    {
        if((j==-1)||(t->data[i]==t->data[j]))
        {
            i++;
            j++;
            next[i]=j;
        }
        else
            j=next[j];
    }

}
int indexKMP(SqString *s,SqString *t,int start,int next[])
{
    int i=start-1,j=0;
    while(i<s->length&&j<t->length)
        if(j==0||s->data[i]==t->data[j])
        {
            i++;
            j++;
        }
        else
            j=next[j];
        if(j>=t->length)
            return i-t->length+1;
        else
            return t->length+1;
}

int main()
{
//使用KMP算法完成串的模式匹配
     SqString s,t;
     initString(&s);
     initString(&t);
     int i,next[100];
     char str1[INITSIZE];
     char str2[INITSIZE];
     gets(str1);
     strAssign(&s,str1);
     gets(str2);
     strAssign(&t,str2);
     int pos,c;
       getNext(&t,next);
        scanf("%d",&pos);
       for(i=0;i<t.length;i++)
        printf("%d ",next[i]);
       printf("\n");
       c=indexKMP(&s,&t,pos,next);
       printf("%d",c);
       return 0;
}

3.3 加上通配符?

编写一个具有通配符?的模式匹配算法。?可以与任意一个字符匹配。
【输入形式】

输入主串s;

输入子串t;

输入比较起始位置pos。

【输出形式】

输出匹配结果:子串第一次出现的位置,若未找到,输出0。
【样例输入1】

there are many cats.

?re

1

【样例输出1】

3

【样例输入2】

thsdfiewnjf fsdfdsjewd

f??f

3

【样例输出2】

13

#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 100
#define ERROR 0
#define OK 1
typedef struct{
  char *data;
  int length;
  int stringsize;
}SqString;
//串的初始化
int initString(SqString *s)
{
    s->data=(char*)malloc(sizeof(char));
    if(!s->data) return 0;
    s->length=0;
    s->stringsize=MAXSIZE;
    return 1;

}
//串的复制
int strAssign(SqString *s, char *str )
{
    int i;
    for(i=0;str[i]!='\0';i++)
        s->data[i]=str[i];
    s->data[i]='\0';
    s->length=i;
    return 1;

}
//带统配符的模式匹配
int indexPattern(SqString *s,SqString *t,int start)
{
    int i=start-1,j=0;
    while(i<s->length&&j<t->length){
        if(s->data[i]==t->data[j]||s->data[i]=='?'||t->data[j]=='?'){
            i++;
            j++;
        }
        else{
            i=i-j+1;
            j=0;
        }
    }
    if(j>=t->length)
        printf("%d ",i-t->length+1);
    else
        printf("0");
}

int main()
{
    SqString s,t;
    int start;
    char str[MAXSIZE];
    //以下补充代码实现接收数据,输出结果
    initString(&s);
    initString(&t);
    gets(str);
    strAssign(&s,str);
    gets(str);
    strAssign(&t,str);
    int pos;
    scanf("%d",&pos);
    indexPattern(&s,&t,pos);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会喷火的小火龙

你的鼓励是我最大的创作动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值