C语言练习-day18

本文介绍了四个关于顺序表的操作:删除所有重复元素,实现两个顺序表的位置互换,合并两个有序顺序表以及在递增有序表中查找并交换元素。每个操作都通过C语言实现,涉及数组操作和算法设计,包括遍历、比较、逆置等技术。
摘要由CSDN通过智能技术生成

题目:从顺序表中删除所有其值重复的元素,使表内所有元素的值均不同。

输入:表长length,以及表中各元素的值,类型为int。

输出:删除重复元素后,表内的值依次输出。

优化目标:无

算法思想:搜索整个顺序表,用k值是存储不重复的元素的序号,每次遍历到一个元素时,就与之前已遍历的元素进行比较(是否相等),若有相等的继续往后遍历。flag是由于判断是否有相等的值。

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

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;


void Del_repeat(SqList &L){
	int i,k,j,flag;
	k = 1;
	for(i = 1;i<=L.length;i++){
		flag = 0;
		for(j=1;j<i;j++){
			if(L.R[j].key==L.R[i].key){
				flag = 1;
			}
		}
		if(flag == 0){
			L.R[k].key = L.R[i].key;
			k++;
		}
	}
	L.length = k-1;
	
}

void ListInit(SqList &L){
	int i,length,key;
	printf("请输入顺序表的长度(小于20):");	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	


	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}


void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	PrintList(L);
	
	
	Del_repeat(L);
	
	PrintList(L);
	
	return 0;
}

题目:已知在一维数组R[m+n]中依次存放两个线性表(a1,a2,a3,...,am)和(b1,b2,b3,...,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,...,bn)放在(a1,a2,a3,...,am)的前面。

输入:表长length,以及表中各元素的值,类型为int;前一个顺序表的长度m,类型为int。

输出:两个顺序表的位置交换后,表内的值依次输出。

优化目标:无

算法思想:先将数组R中全部元素原地逆置(bn,...,b2,b1,am,...,a2,a1),再对前n个元素和后m个元素分别使用逆置算法,即可得到(b1,b2,...,bn,a1,a2,..,am),从而实现顺序表的位置交换。



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

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

void Reverse_m_n(SqList &L,int left,int right){

	int i = 1;
	KeyType x;
	for(i = 1;i<=((left+right)/2-left+1);i++){
		x = L.R[left+i-1];
		L.R[left+i-1] = L.R[right-i+1];
		L.R[right-i+1] = x;
	}
}

void ListInit(SqList &L){
	int i,length,key;
	printf("请输入顺序表的长度(小于20):");	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}


void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	
	PrintList(L);
	
	printf("请输入前一个顺序表的大小:");
	int m;
	scanf("%d",&m);
	
	Reverse_m_n(L,1,L.length);
	Reverse_m_n(L,1,m);
	Reverse_m_n(L,m+1,L.length);

	PrintList(L);
	
	return 0;
}

题目:将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。

输入:两个顺序表的各表长length,以及表中各元素的值,类型为int。

输出:合并顺序表后,将原两个顺序表和合并后的顺序表的表内的值依次输出。

优化目标:无

算法思想:首先,按顺序不断取下两个顺序表表头较小的结点存入新的顺序表中。然后,看哪个表还有剩余,将剩下的部分加到新的顺序表后面。



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

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

void Conbination(SqList L1,SqList L2,SqList &L){
	L.length = 0;
	int n;
	for(n = 1;n<=MAXSIZE;n++){
		L.R[n].key = 0;
	}
		
		
		
	int i = 1,k = 1,j = 1;
	while(i<=L1.length&&j<=L2.length){
		if(L1.R[i].key>L2.R[j].key){
			L.R[k++].key = L2.R[j++].key;
		}
		else{
			L.R[k++].key = L1.R[i++].key;
		}
	}
	while(i<=L1.length){
		L.R[k++].key = L1.R[i++].key;
	}
	while(j<=L2.length){
		L.R[k++].key = L2.R[j++].key;
	}
	L.length = k-1;
}

void ListInit(SqList &L){
	int i,length,key;
	printf("请输入顺序表的长度(小于20):");	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}


void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L1,L2,L;
	ListInit(L1);
	PrintList(L1);
	
	ListInit(L2);
	PrintList(L2);
	
	
	Conbination(L1,L2,L);
	
	PrintList(L1);
	PrintList(L2);
	PrintList(L);
	
	return 0;
}

题目:线性表(a1,a2,a3,...,an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换,若找不到,则将其插入表中并使表中元素仍递增有序。

输入:表长length,以及表中各元素的值,类型为int;要查找的元素x,类型为int。

输出:查找后,表内的值依次输出。

优化目标:无

算法思想:顺序存储的线性表递增有序,这里采用折半查找法。



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

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

void SearchExchange(SqList &L,int x){

	int low = 1,high = L.length,mid;
	while(low<high){
		mid = (low +high)/2;
		if(L.R[mid].key == x){
			break;
		}
		else if(L.R[mid].key>x){
			high = mid-1;
		}
		else{
			low = mid+1;
		}
	}
	if(L.R[mid].key == x&&mid != L.length){
		KeyType k = L.R[mid];
		L.R[mid] = L.R[mid+1];
		L.R[mid+1] = k;
		
	}
	if(low>high){
		for(int i=L.length;i>high;i--){
			L.R[i+1] = L.R[i];
		}
		L.R[high+1].key = x;
		L.length++;
	}
	
}

void ListInit(SqList &L){
	int i,length,key;
	printf("请输入顺序表的长度(小于20):");	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}


void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	
	PrintList(L);
	
	int x;
	printf("请输入查找的数:");
	scanf("%d",&x);
	SearchExchange(L,x);

	PrintList(L);
	
	return 0;
}

题目:设将n(n>1)个整数存放到一维数组R中。将R中保存的序列循环左移p(0<p<n)个位置。

输入:表长length,以及表中各元素的值,类型为int。

输出:顺序表循环左移p个位置后,表内的值依次输出。

优化目标:无

算法思想:将顺序表R看成数组ab,所以问题就转变为将ab转换为ba,所以先将整个数组逆置,再分别在b和a的部分逆置就得到了结果。



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

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

void Reverse_m_n(SqList &L,int left,int right){

	int i = 1;
	KeyType x;
	for(i = 1;i<=((left+right)/2-left+1);i++){
		x = L.R[left+i-1];
		L.R[left+i-1] = L.R[right-i+1];
		L.R[right-i+1] = x;
	}
}

void Converse(SqList &L,int m){
	Reverse_m_n(L,1,L.length);
	Reverse_m_n(L,1,L.length-m);
	Reverse_m_n(L,L.length-m+1,L.length);
}

void ListInit(SqList &L){
	int i,length,key;
	printf("请输入顺序表的长度(小于20):");	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}


void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	
	PrintList(L);
	
	printf("请输入需要左移的大小:");
	int m;
	scanf("%d",&m);
	
	Converse(L,m);

	PrintList(L);
	
	return 0;
}

今天完成了五个顺序表的题,最大的收获就是将数组左移的思想,先全部元素逆置,再分别逆置各部分。所以还要继续学习,明天还有一些顺序表的题,后面就开始做链表的题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值