数据结构实验题目

1、已知单链表L(带头节点)是一个递增有序表,试编写一算法,删除表中值大于min且小于max的节点(若表中有这样的节点),同时释放被删节点的空间,这里min和max是两个给定参数。请分析算法时间复杂度。

#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct LNode{
	int a;
	LNode *next;
};
LNode *init_List(int n){              //初始化链表 
	LNode *L;
    L=(LNode *)malloc(sizeof(LNode));
    L->next=NULL;
	LNode *p;
	LNode *r = L; 
	if(n!=0){
		int x;
	    while(n--){
		    scanf("%d",&x);
	    	p=(LNode *)malloc(sizeof(LNode));
	    	p->a = x;
	    	p->next = NULL; 
	    	r->next = p;              //使用尾插法 
	    	r = p;
		}	
	}
	return L;	
}
void print_List(LNode *L){            //输出链表内容 
	LNode *p=L->next;
	if(L->next==NULL){
		printf("-1\n");
		return;
	}
    while(p->next != NULL){
		printf("%d ",p->a); p = p->next;
	}
	printf("%d\n",p->a);
} 

LNode *delete2(LNode *L,int min,int max){       //删除指定区域内的节点 
	LNode* p=L->next,*q=L,*r;
	if(L->next==NULL){
		return L;
	}
	while(p!=NULL){
		if(p->a > min && p->a < max){
			r=p;
			q->next=p->next;
			p=q->next;
        	free(r);                           //释放被删除节点的空间 
		}
		else{
			p=p->next;
		    q=q->next;
		}	
	}
	return L;
}
int main(){
	int T,len,q,type,min,max;
	LNode * L;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&len);
		L=init_List(len);
		scanf("%d",&q);
		    while(q--){
		    	scanf("%d",&type);
		    	if(type==1){
		    		print_List(L);
				}
				else if(type==2){
					scanf("%d%d",&min,&max);
					L=delete2(L,min,max);
				}
			}	
	}
	return 0;
}

2、约瑟夫环问题

1)问题描述:有编号为1, 2…n 的 n 个人按顺时针方向围坐一圈,每人持有一个正整数密码。开始给定一个正整数 m,从第一个人按顺时针方向自1开始报数,报到m者出列,不再参加报数,这时将出列者的密码作为m,从出列者顺时针方向的下一人开始重新自1开始报数。如此下去,直到所有人都出列。试设计算法,输出出列者的序列。

2)实验要求:采用顺序和链式两种存储结构实现

#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
	int m;                  //m记录密码 
	int num;                //记录初始的位置 
	Node *next;             //下一个节点 
}; 
int count;
Node* init_List(int n){
	int num=1;
	Node* L,*r,*p;
	int m;
	L = (Node*)malloc(sizeof(Node));
	L->next = NULL;
	r=L;                   //尾插法 
	if(n==0) return L;
	else{
		count=0;
		while(n--){
			p = (Node*)malloc(sizeof(Node));
			scanf("%d",&m);
			count++;       //记录节点数 
			p->m = m;
			p->num = num++; 
			p->next = NULL;
			r->next = p;
			r = p;
		}
	}
	r->next = L->next;  
	return L;
}
void xunhuan_List(Node* L,int m){
	Node *p=L->next,*r=L,*q1;
	int m1=m;
	while(count != 1 ){          //原表中剩一节点则结束 
		m1-=1;                   //第一次从本身开始
	    while(m1--){
		    r=r->next;
		    p=p->next;
	    }
	    printf("%d ",p->num); 	    
	    count--; 
	    if(p->m!=0) m1=p->m;
	    else m1=m;
	    r->next = p->next;       //改变原来的链接关系 
	    p = r->next;
	}
	printf("%d\n",p->num);
}

int main(){
	int a,n,m;
	scanf("%d",&a);
	while(a--){
		Node *L;
	    scanf("%d",&n);	
		L = init_List(n);
		scanf("%d",&m);             //初始密码 
		xunhuan_List(L,m);          //循环 
	} 
	return 0;
}

3.一元稀疏多项式简单的计算器

1)问题描述:用线性表表示一元稀疏多项式,设计一个一元多项式运算器。

2)实验要求: 采用单链表存储结构一元稀疏多项式,输入并建立多项式,输出多项式,实现多项式加、减运算。

 

#include<iostream>           //多项式问题 
#include<cstdlib>
using namespace std;
typedef struct Node{
	int x;
	int y;
	Node* next;
}; 
Node* init_List(int n){
	Node *L,*p,*r;
	int x,y;
	L=(Node*)malloc(sizeof(Node));
	L->next = NULL;
	r=L;
	if(n==0){                 //使用尾插法 
		return L;
	}
	else{
		while(n--){
			scanf("%d%d",&x,&y);
			p=(Node*)malloc(sizeof(Node));
			p->x=x;
			p->y=y;
			p->next = NULL;
			r->next = p;
			r=p;
		}
	}
	return L;
}
void print_List(Node *L){            //输出链表内容 
	Node *p=L->next;
	if(L->next==NULL){
		printf("-1\n");
		return;
	}
	if(p->x>0){
		printf("%dX^%d",p->x,p->y);
		p=p->next; 
	}
	if(p==NULL){
		printf("\n");
		return;
	}
	else{
	    while(p->next != NULL){
    	if(p->x>0){
    		printf("+%dX^%d",p->x,p->y); 
		    p = p->next;
		}
		else if(p->x<0){
			printf("%dX^%d",p->x,p->y); 
		    p = p->next;
		}
		else if(p->x == 0){
			printf("");
			p=p->next;
		}
	}
	if(p->x>0){
		printf("+%dX^%d\n",p->x,p->y); 
	}
	else if(p->x<0){
		printf("%dX^%d\n",p->x,p->y); 
	}
	else if(p->x == 0){
		printf("\n");
	}	 
	}
 
} 
Node* jian_List(Node* L1,Node* L2){
	Node *p1=L1,*p2=L2->next,*r;
	int flag;
	while(p2!=NULL){
		p1=L1->next;
		flag=0;
	    while(p1!=NULL){
	    	if(p1->y==p2->y){
	    		flag=1;
	    		p1->x =p1->x - p2->x;
			}
			p1=p1->next;
		}
		if(flag==0 && p1==NULL){
			Node* p;
			r=L1->next;
			while(r->next!=NULL) r=r->next;
			p=(Node*)malloc(sizeof(Node));
			p->x = -(p2->x);
			p->y = p2->y; 
			p->next = NULL;
			r->next = p;
			r=p;	
		}
		p2=p2->next;
	} 
	return L1;
}
Node* add_List(Node* L1,Node* L2){
	Node *p1=L1,*p2=L2->next,*r;
	int flag;
	while(p2!=NULL){
		p1=L1->next;
		flag=0;
	    while(p1!=NULL){
	    	if(p1->y == p2->y){
	    		flag=1;
	    		p1->x = p1->x + p2->x;
			}
			p1=p1->next;
		}
		if(flag==0 && p1==NULL){
			Node* p;
			r=L1->next;
			while(r->next!=NULL) r=r->next;
			p=(Node*)malloc(sizeof(Node));
			p->x = p2->x;
			p->y = p2->y; 
			p->next = NULL;
			r->next = p;
			r=p;	
		}
		p2=p2->next;
	}
	return L1;
}
int main(){
	int T,m,n,p,type;
	scanf("%d",&T);
	while(T--){
		Node *L1,*L2,*L21,*L22;
	    scanf("%d%d",&m,&n);
		L1=init_List(m);             //初始化多项式1 
		L2=init_List(n);             //初始化多项式2 
		scanf("%d",&p);
		while(p--){
			scanf("%d",&type);
			if(type==1){
				print_List(L1);
				print_List(L2);
			}
			else if(type==2){        //加运算 
				L1 = add_List(L1,L2);
			}
			else if(type==3){        //减运算 
				L1 = jian_List(L1,L2);
			}
		}	
	}
	return 0;
}

4.十进制数到N进制数的转换

1)问题描述:将从键盘输入的十进制数转换为N(如二进制、八进制、十六进制)进制数据。

2)实验要求: 利用顺序栈实现数制转换问题

3) 实现提示:

  • 转换方法利用辗转相除法;
  • 所转换的N进制数按低位到高位的顺序产生,而通常的输出是从高位到低位的,恰好与计算过程相反,因此转换过程中每得到一位N进制数则进栈保存,转换完毕后依次出栈则正好是转换结果。

4)注意问题:

  • 何时入栈、出栈

       算法结束条件

#include<iostream>
using namespace std;
#include<cstdlib>
#include<cstring>
#define Max_Size 100
typedef struct SeqStack {
	char data[Max_Size];
	int top;
};
SeqStack *initStack() {        //初始化栈 
	SeqStack *s;
	s = (SeqStack *)malloc(sizeof(SeqStack));
	if (s != NULL)
		s->top = -1;
	return s;
}

void Push(SeqStack *s, int x) {  //入栈 
	if (s->top == Max_Size) {
		return;
	}
	else {
		s->top++;
		s->data[s->top] = x;
	}
	return;
}

int Pop(SeqStack *s) {          //出栈 
	char temp;
	if (s->top == -1) {
		return 0;
	}
	else {
		temp = s->data[s->top];
		s->top--;
	}
	printf("%c",temp);
}
int main(){
	SeqStack *s;
	s = initStack();           //2<=n<=36 
    int x,n;
    scanf("%d%d",&x,&n);
    int count=0;
    if(x == 0){ 
    	Push(s,0);
    }
    int r;
    while(x != 0){            //中间利用辗转相除法 
        r = x % n; 
        if(r >= 10 && r<=35){ //大于10就转化为相应的字母 
            Push(s,r+55);     //根据ASCALL码转换
		}
        else{                 //小于10就转化为相应数字 
            Push(s,r+'0');
        }
        count++;
        x /= n;
    }
    while(s->top != -1) {  //循环依次输出栈中的内容 
        Pop(s);	
	}
    return 0;
}

5.判断“回文”问题

1)问题描述:所谓回文,是指从前向后顺读和从后向前倒读都一样的字符串。

例如,did;  pop;  I was able 与 elba saw I 等等。

2)实验要求:编写程序,利用栈结构判断一个字符串是否是“回文”。

3)实现提示:

从左向右遇到的字符,若和栈顶元素比较,若不相等,字符入栈,若相等,出栈。如此继续,若栈空,字符串是“回文”,否则不是。

#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std; 
typedef struct Node{          //栈 
	int data[200];
	int top;
};
Node *init_List(){           //建立栈 
	Node *L;
	L = (Node*)malloc(sizeof(Node));
	L->top=-1;
	return L;
} 

Node* push(Node* L,char x){   //入栈 
	L->top++;
	L->data[L->top] = x; 
	return L;
} 

Node* pop(Node* L){         //出栈 
	L->top--;
	return L;
}

int main(){
	char a[200],b;
	int i=0;
    Node* L;
	L = init_List();
	int n=0; 
	
	while((b=getchar()) && b!='\n'){
		a[i++] = b;
		n++;
	} 
	
	if(n%2==1){
		for(i=(n-1)/2;a[i]!='\0';i++){    //中间数字之后的前移 
			a[i] = a[i+1];
		}
		n=n-1;
	}                                     //end 全部变成偶数个字符 
	
	for(i=0;i<n/2;i++){                  //前n/2个入栈 
		L = push(L,a[i]);
	}                                
	
	for(i=n/2;L->top!=-1;i++){           //从第n/2个开始逐个与栈内的元素对比 
		if(a[i] != L->data[L->top]){
			printf("NO"); 
			break;
		}
		L = pop(L);
	}
	if(L->top == -1){
		printf("YES");
	} 
	return 0;
}

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小wal

您的肯定是我创作的动力,谢谢。

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

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

打赏作者

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

抵扣说明:

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

余额充值