这里写目录标题
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;
}