线性表的顺序表示--王道2024DS习题代码

2023-11-17

2024年王道数据结构考研复习指导第二章:线性表的顺序表示——课后综合应用题个人学习的相关运行代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define InitSize 10 //表长度的初始定义
#define INT_MAX 0x7fffffff 
typedef struct{
	int *data;		//指示动态分配数组的指针 
	int MaxSize;	//顺序表的最大容量 
	int length;		//顺序表的当前长度 
}SeqList; 			//顺序表类型定义-动态分配 

void InitList(SeqList &L){
	//用malloc函数申请一片连续的存储空间
	L.data=(int *)malloc(InitSize*sizeof(int));
	L.length=0;
	L.MaxSize=InitSize; 
}

//增加动态数组的长度 
void IncreaseSize(SeqList &L, int len){
	int *p=L.data;
	L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
	for(int i=0; i<L.length; i++){
		L.data[i]=p[i];				//将数据复制到新区域 
	}
	L.MaxSize=L.MaxSize+len;		//顺序表的最大长度增加 len 
	free(p);						//释放原来的内存空间 
}

//创建一个顺序表
void CreateList(SeqList &L){
	int num;
	printf("\n\t请输入所需顺序表的长度:");
	scanf("%d", &num); 
	printf("\n\t请输入顺序表内容:");
	for(int k=0; k<num; k++){
		scanf("%d", &L.data[k]);
		L.length++;
	}
} 

//按值查找
int LocateElem(SeqList &L, int e){
	int i;
	for(i=0; i<L.length; i++){
		if(L.data[i]==e){
			return i+1;
		}
	}
	return 0;
} 

//折半查找法
void SearchExchangeInsert(SeqList &L, int x){
	int low=0, high=L.length-1, mid, t, i;
	while(low<=high){
		mid=(low+high)/2;
		if(L.data[mid]==x) break;
		else if(L.data[mid]<x) low=mid+1;
		else high=mid-1;
	}
	if(L.data[mid]==x&&mid!=L.length-1){
		t=L.data[mid];
		L.data[mid]=L.data[mid+1];
		L.data[mid+1]=t;
	}
	else if(low>high){
		L.length++;
        for(i=L.length-2; i>high; i--) L.data[i+1]=L.data[i];
        L.data[i+1]=x;
    }
} 

//插入函数
bool ListInsert(SeqList &L, int i, int e){
	if(i<1||i>L.length+1){
		printf("输入的位序无效!\n");
		return false;
	}
	if(L.length>=L.MaxSize){
		printf("当前存储空间已满,无法插入。\n");
		return false;
	}
	for(int j=L.length;j>=i;j--)
		L.data[j]=L.data[j-1];
	L.data[i-1]=e;
	L.length++;
	return true; 
}

//输出函数
void PrintList(SeqList &L){
	printf("\n\t顺序表内容为:");
	for(int i=0; i<L.length; i++){
		printf("%d ", L.data[i]);
	}
	printf("\n");
}

//删除最小值
bool Del_Min(SeqList &L, int &min){
	if(L.length==0){
		printf("\n\t表空,无法删除元素。\n");
		return false; 
	}
	min=L.data[0];
	int pos=0;
	for(int i=1; i<L.length; i++){
		if(L.data[i]<min){
			min=L.data[i];
			pos=i;
		}
	}
	L.data[pos]=L.data[L.length-1];
	L.length--;
	return true;
}

//逆置整个顺序表 
void Reverse(SeqList &L){
	int temp;
	for(int i=0; i<L.length/2; i++){
		temp=L.data[i];
		L.data[i]=L.data[L.length-i-1];
		L.data[L.length-i-1]=temp;
	}
	printf("\n\t成功逆置顺序表内容!\n");
	PrintList(L);
}

//逆置从from到to的内容
void Reverse_from_to(SeqList &L, int from, int to){
	int i, temp;
	for(i=0; i<(to-from+1)/2; i++){
		temp=L.data[from+i];
		L.data[from+i]=L.data[to-i];
		L.data[to-i]=temp;
	}
} 

//序列可左移p个位置
void Converse(SeqList &L, int n, int p){
	Reverse_from_to(L, 0, p-1);
	Reverse_from_to(L, p, n-1);
	Reverse_from_to(L, 0, n-1);
} 

//删除所有值为x的数据元素
void Del_x(SeqList &L, int x){
	int k=0, i;
	for(i=0; i<L.length; i++){
		if(L.data[i]!=x){
			L.data[k]=L.data[i];
			k++;
		}
	}
	L.length=k;
	printf("\n\t成功删除x!\n");
	PrintList(L);
} 

//删除表中s-t之间的所有元素
bool Del_s_t(SeqList &L, int s, int t){
	int k=0, i;
	if(L.length==0){
		printf("\n\t顺序表内容为空,无法删除!\n");
		return false;
	}if(s>=t|| L.data[L.length-1]<s|| L.data[0]>t){
		printf("\n\t给定值s、t不合理,无法删除!\n");
		return false;
	}for(i=0; i<L.length; i++){
		if(L.data[i]<s||L.data[i]>t){
			L.data[k]=L.data[i];
			k++;
		}
	}
	L.length=k;
	printf("\n\t成功删除s-t之间数据元素!\n");
	return true;
} 

//删除表中重复的元素
bool Del_Same(SeqList &L){
	if(L.length==0){
		printf("\n\t顺序表内容为空,无法删除!\n");
		return false;
	}
	int i, j;
	for(i=0, j=1; j<L.length; j++)	//查找下一个与上个元素不同的值 
		if(L.data[i]!=L.data[j])
			L.data[++i]=L.data[j];
	L.length=i+1;
	printf("\n\t成功删除重复的数据元素!\n");
	return true;
}

//合并两个有序表并输出
bool Merge(SeqList A, SeqList B, SeqList &C){
	if(A.length+B.length>C.MaxSize){
		printf("\n\t合并后长度超过限度,无法合并!\n");
		return false;
	}
	int i=0, j=0, k=0;
	while(i<A.length&&j<B.length){	//循环比较,小者先存入结果表 
		if(A.data[i]<=B.data[j])
			C.data[k++]=A.data[i++];
		else
			C.data[k++]=B.data[j++];
	}
	while(i<A.length)
		C.data[k++]=A.data[i++];
	while(j<B.length)
		C.data[k++]=B.data[j++];
	C.length=k;		//已经k++过所以长度为k 
	printf("\n\t合并成功!合并后表内容如下:\n");
	return true;	
} 

//交换线性表位置
bool Exchange(SeqList &A, SeqList &B, SeqList &C){
	int nb=B.length;
	for(int k=0; k<C.length; k++){
		if(nb!=0){
			C.data[k]=B.data[k];
			nb--;
		}else{
			C.data[k]=A.data[k-C.length+A.length];
		}	
	}
	C.length=A.length+B.length;
	printf("\n\t成功交换线性表位置!\n");
	return true;
} 

//求序列A和B的中位数
int M_Search(SeqList &A, SeqList &B){
	int s1=0, d1=A.length-1, m1, s2=0, d2=B.length-1, m2;
	//分别表示序列A和B的首位数、末位数和中位数
	while(s1!=d1||s2!=d2){
		m1=(s1+d1)/2;
		m2=(s2+d2)/2;
		if(A.data[m1]==B.data[m2])
			return A.data[m1];		//两个序列中位数相等,取任一为中位数,结束 
		if(A.data[m1]<B.data[m2]){	//若a<b则舍弃A中较小一半和B中较大一半,且舍弃长度相等 
			if((s1+d1)%2==0){		//若元素个数为奇数 
				s1=m1;				//舍弃A中间点以前的部分且保留中间点 
				d2=m2;				//舍弃B中间点以后的部分且保留中间点 
			}
			else{					//元素个数为偶数 
				s1=m1+1;			//舍弃A中间点及中间点以前部分 
				d2=m2;				//舍弃B中间点以后部分且保留中间点 
			}
		}
		else{						//若a>b则舍弃A中较大一半和B中较小一半,且舍弃长度相等
			if((s2+d2)%2==0){ 		//若元素个数为奇数
				d1=m1;				//舍弃A中间点以后的部分且保留中间点
				s2=m2;				//舍弃B中间点以前的部分且保留中间点
			}
			else{					//元素个数为偶数
				d1=m1;				//舍弃A中间点以后部分且保留中间点 
				s2=m2+1;			//舍弃B中间点及中间点以前部分
			}
		}
	} 
	//较小者为中位数 
	return A.data[s1]<B.data[s2]?A.data[s1]:B.data[s2];
} 

//摩尔投票法-找>n/2主元素
int Majority(SeqList &A){
	int i, c, count=1;				//c用来保存候选主元素,count用来计数 
	c=A.data[0];					//设置A.data[0]为主元素 
	for(i=1; i<A.length; i++){		//查找主元素 
		if(A.data[i]==c)
			count++;				//对A的候选主元素计数 
		else
			if(count>0)				//处理不是候选主元素的情况 
				count--;
			else{					//更换候选主元素,重新计数 
				c=A.data[i];
				count=1;
			}
	}
	if(count>0)
		//统计候选主元素实际出现次数 
		for(i=count=0; i<A.length; i++)
			if(A.data[i]==c)
				count++;			 
	if(count>A.length/2) return c;	//确认候选主元素 
	else return -1;					//不存在主元素 
}

//寻找最小正整数
int FindMinPosInt(SeqList &L){
	int i;
	int B[L.length];
	memset(B,0,sizeof(B));			//创建数组并赋初值为0 
	for(i=0; i<L.length; i++)
		if(L.data[i]>0&&L.data[i]<=L.length)
			B[L.data[i]-1]=1;		//若L.data[i]的值介于1~n则标记数组B 
	for(i=0; i<L.length; i++)		//扫描数组B,找到目标值 
		if(B[i]==0) break;
	return i+1;						//返回结果 
} 

//三元组找最小距离D
//计算绝对值 
int abs_(int a){
	if(a<0) return -a;
	else return a;
}
//a是否是三个数中的最小值
bool xls_min(int a, int b, int c){
	if(a<=b&&a<=c) return true;
	return false;
} 
//寻找最小距离
int FindMinofTrip(SeqList &A, SeqList &B, SeqList &C){
	//D_min用于记录三元组的最小距离,初值赋为INT_MAX 
	int D_min=INT_MAX, i=0, j=0, k=0, D;
	while(i<A.length&&j<B.length&&k<C.length&&D_min>0){
		D=abs_(A.data[i]-B.data[j])+abs_(B.data[j]-C.data[k])+abs_(C.data[k]-A.data[i]);	//计算D
		if(D<D_min) D_min=D;									//更新D 
		if(xls_min(A.data[i], B.data[j], C.data[k])) i++;		//更新a 
		else if(xls_min(B.data[j], C.data[k], A.data[i])) j++;
		else k++;
	} 
	return D_min;
} 

int main(){
	SeqList L;		//声明一个顺序表 
	SeqList a, b;
	SeqList S1, S2, S3;
	InitList(L);	//初始化顺序表
	int i=1, choice;
	int c, na;
	while(i)
	{
		printf("\n\t***************顺  序  表****************"); 
		printf("\n\t*                                       *");
		printf("\n\t*       0--创建一个顺序表               *"); 
		printf("\n\t*       1--删除最小元素并输出           *"); 
		printf("\n\t*       2--逆置顺序表内容               *");
		printf("\n\t*       3--删除所有值为x的数据元素      *");
		printf("\n\t*       4--删除有序表s-t之间元素        *");
		printf("\n\t*       5--删除表中重复的元素           *");
		printf("\n\t*       6--合并两个有序表并输出         *");
		printf("\n\t*       7--合并两表并交换位置           *");
		printf("\n\t*       8--折半查值或插入有序表         *");
		printf("\n\t*       9--序列可左移p个位置            *");
		printf("\n\t*      10--求序列A和B的中位数           *");
		printf("\n\t*      11--摩尔投票法找>n/2主元素       *");
		printf("\n\t*      12--寻找最小正整数               *");
		printf("\n\t*      13--三元组找最小距离D            *");
		printf("\n\t*      -1--返     回                    *");  
		printf("\n\t*                                       *");
		printf("\n\t*****************************************"); 
		printf("\n\t请选择菜单号(0--10):"); 
		scanf("%d",&choice);
		switch(choice)
		{
			case 0:
				CreateList(L);
				break;
			case 1:
				int min;
				if(Del_Min(L, min)){
					printf("\n\t被删除的最小元素为:%d\n", min);
					PrintList(L);
				}
				break;
			case 2:
				Reverse(L);
				break;
			case 3:
				int x;
				printf("\n\t请输入所需删除的数据元素x:");
				scanf("%d", &x);
				Del_x(L, x);
				break;
			case 4:
				int s, t;
				printf("\n\t请输入所需删除的范围s-t:");
				scanf("%d %d", &s, &t); 
				Del_s_t(L, s, t);
				PrintList(L);
				break; 
			case 5:
				Del_Same(L);
				PrintList(L);
				break;
			case 6:
				SeqList A, B;		//声明一个顺序表 
				InitList(A);
				InitList(B);
				printf("\n\t开始建表A\n");
				CreateList(A);
				printf("\n\t开始建表B\n");
				CreateList(B);
				Merge(A, B, L);
				PrintList(L);
				break;
			case 7:
				InitList(a);
				InitList(b);
				printf("\n\t开始建线性表a\n");
				CreateList(a);
				printf("\n\t开始建线性表b\n");
				CreateList(b);
				c=a.length+b.length;
				na=a.length;
				for(int k=0; k<c; k++){
					if(na!=0){
						L.data[k]=a.data[k];
						na--;
					}else{
						L.data[k]=b.data[k-c+b.length];
					}	
				}
				L.length=a.length+b.length;
				printf("\n\t原一维数组A[m+n]的内容合并完成!\n");
				PrintList(L);
				Exchange(a, b, L);
				PrintList(L);
				break;
			case 8:
				int e;
				printf("\n\t请输入所需查找的数据元素e:");
				scanf("%d", &e);
				c=LocateElem(L, e);
				if(c!=0){
					na=L.data[c-1];
					L.data[c-1]=L.data[c];
					L.data[c]=na;
					printf("\n\t找到了e值,并成功交换!\n");
					PrintList(L);
				}else{
					//na=L.length+1;
					//for(int k=0; k<L.length; k++){
					//	if(e<L.data[k]){
					//		na=k+1;
					//		return na;
					//	}	
					//} 
					//ListInsert(L, na, e);
					SearchExchangeInsert(L, e);
					printf("\n\t没有找到e值,成功插入表中!\n"); 
					PrintList(L);
				}
				break;
			case 9:
				int p;
				printf("\n\t请输入所需左移的位数p:");
				scanf("%d", &p);
				Converse(L, L.length, p);
				PrintList(L);
				break;
			case 10:
				InitList(a);
				InitList(b);
				printf("\n\t开始建升序序列A\n");
				CreateList(a);
				printf("\n\t开始建升序序列B\n");
				CreateList(b);
				c=M_Search(a, b);
				printf("\n\t两个升序序列的中位数为:%d\n", c);
				break; 
			case 11:
				c=Majority(L);
				if(c==-1)
					printf("\n\t不存在主元素!\n"); 
				else
					printf("\n\t主元素为:%d\n", c);
				break; 
			case 12:
				c=FindMinPosInt(L);
				printf("\n\t找到最小正整数为:%d\n", c);
				break;
			case 13:
				InitList(S1);
				InitList(S2);
				InitList(S3);
				printf("\n\t开始建非空升序数组S1\n");
				CreateList(S1);
				printf("\n\t开始建非空升序数组S2\n");
				CreateList(S2);
				printf("\n\t开始建非空升序数组S3\n");
				CreateList(S3);
				c=FindMinofTrip(S1, S2, S3);
				printf("\n\t找到三元组最小距离D为:%d\n", c);
				break; 
		    case -1:
				i=0;
		    	break;
		}	
	}
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线性表的顺序表示--王道2024DS习题代码 的相关文章

随机推荐

  • 微服务网关 —— SpringCloud Gateway

    Gateway 简介 Spring Cloud Gateway 基于 Spring 5 Spring Boot 2 和 Project Reactor 等技术 是在 Spring 生态系统之上构建的 API 网关服务 Gateway 旨在提
  • 剑指offer 06 从尾到头打印链表

    题目 从尾到头打印链表 输入一个链表的头节点 从尾到头反过来返回每个节点的值 用数组返回 示例 输入 head 1 3 2 输出 2 3 1 题解一 栈 解法 遍历链表 将所有遍历到的值压入栈中 再利用栈 后进先出 的特性 从尾到头打印链表
  • STM32 进阶教程 1 - micropython 移植

    前言 Python是一种解释型 面向对象 动态数据类型的高级程序设计语言 Python 是一个高层次的结合了解释性 编译性 互动性和面向对象的脚本语言 具有如下特点 1 易于学习 Python有相对较少的关键字 结构简单 和一个明确定义的语
  • ChatGPT Prompting开发实战(五)

    一 如何编写有效的prompt 对于大语言模型来说 编写出有效的prompt能够帮助模型更好地理解用户的意图 intents 生成针对用户提问来说是有效的答案 避免用户与模型之间来来回回对话多次但是用户不能从LLM那里得到有意义的反馈 本文
  • outbound和inbound关系

    Inbound PCI域訪问存储器域 Outbound 存储器域訪问PCI域 RC訪问EP RC存储器域 gt outbound gt RC PCI域 gt EP PCI域 gt inbound gt EP存储器域 EP訪问RC EP存储器
  • python实现主成分估计

    什么是PCA 主成分分析的主要目的是希望用较少的变量去解释原来资料中的大部分变异 将我们手中许多相关性很高的变量转化成彼此相互独立或不相关的变量 通常是选出比原始变量个数少 能解释大部分资料中的变异的几个新变量 即所谓主成分 并用以解释资料
  • python编程基础知识

    python 切片 可以对list对象 如 1 2 3 4 字符串对象 1234 进行切片 使用 str l r str截取索引范围为 l r 索引值可以为负 表示从倒数方向 如 1表示倒数第一项 例 str 123456 str 0 2
  • 微信小程序开发之数据存储 参数传递 数据缓存

    微信小程序开发内测一个月 数据传递的方式很少 经常遇到页面销毁后回传参数的问题 小程序中并没有类似Android的startActivityForResult的方法 也没有类似广播这样的通讯方式 更没有类似eventbus的轮子可用 现在已
  • sql_labs18

    刚拿到题目时一点头绪没有 虽然提示是user agent注入 但没登录之前是看不到有关信息的 之后经过查看知道了两个admin就可以登录上 并且可以查看到user agent信息 判断闭合符 在User Agent字段结束添加单引号 触发报
  • esp32开发板学习

    1 esp32简介 esp32说到底就是一个小型的linux 可以执行我们的代码 尺寸只有一个苹果watch se的大小 可以集成各个物理组件 好像是通过开发板上的引脚来操作的 2 开发板部署python环境 2 1 在pdd花10块钱买了
  • 关闭文件指针不对

    浏览代码时看到下面几行代码 大家看看有啥问题 其中隐含的问题是关闭空的文件指针 所以写了一个测试代码 运行一下 挂了
  • C++模板类重载"<<"未定义错误

    在使用C 的模板类进行编程的时候 重载 lt lt 运算符时 如果定义不当 会出现未定义的情况 错误为LNK2019 这个问题的原因是由于C 的模板编译机制造成的 解决问题的方式是在类中声明 lt lt 运算符时 需要在运算符和参数之间的位
  • 【Python-利用动态二维码传输文件(五)】动态二维码文件发送端开发,使用Tkinter filedialog实现任意格式文件选中,并显示发送状态

    之前四篇文章论证了利用二维码传输文件的可行性 本章使用tkinter开发 动态二维码文件发送端 发送端具备文件选择 开始发送文件 停止发送文件以及显示发送状态的功能 程序界面下 这里下载源码运行 使用tkinter开发动态二维码文件发送端
  • 【JVM】JVM 垃圾收集器与内存分配策略

    JVM 垃圾收集器与内存分配策略 由JVM内存区域可知Java运行时内存的各个区域 其中程序计数器 虚拟机栈 本地方法栈3个区域随线程而生 随线程而灭 当方法结束或者线程结束时 内存就会跟着被回收了 而只有处于运行期间 我们才能知道程序究竟
  • 在IMX8MM平台linux下开发rm67191屏驱动

    NXP IMX8M MINI rel imx 4 14 98 2 0 0 ga 屏芯片 rm67191 屏调试记录 1 不能挂设备 设备树删除ADV7535屏的配置adv bridge 不通编译通过 结果按 https community
  • 一起来看看一个体系完善的前端React组件库是如何搭建出来的!

    作者简介 剑桥 携程资深前端开发工程师 关注自动化工具开发 前端工程自动构建相关技术 随着前端工程的发展 组件化的思想早已深入人心 现代的前端框架React Vue等 都是围绕组件设计 组件化的开发模式 大大提高了开发效率 设计和开发高质量
  • 增长率用计算机怎么算,操作方法:Excel使用公式来计算增长率教程

    有关使用公式计算增长率的Excel教程 Excel经常需要使用公式来计算增长率 如何使用公式来计算增长率 以下是有关使用公式计算增长率的excel教程 希望阅读后能为您带来启发 Excel使用公式来计算增长率教程 计算增长率步骤1 在单元格
  • A Survey on Large Language Models for Recommendation

    本文是LLM系列的文章 针对 A Survey on Large Language Models for Recommendation 的翻译 大模型用于推荐的综述 摘要 1 引言 2 建模范式和分类 3 判别式LLM用于推荐 4 生成式L
  • 关于使用Mybatis时实体类字段切记要使用包装类型

    每周的博客从5月份有开始断更了 看来坚持每周写一篇博客缺失很难 不过从这周开始 除了一方面把之前的那几周没写的博客补回来 另一方面从这周开始要真正逼自己的写一篇博客 并争取在7月份前搭建起自己的个人博客网站 好 废话少说 接下来快速进入今天
  • 线性表的顺序表示--王道2024DS习题代码

    2024年王道数据结构考研复习指导第二章 线性表的顺序表示 课后综合应用题个人学习的相关运行代码 include