⚡王道课后题之线性表⚡
1|01.搜索顺序表,查找最小值元素,用最后的元素代替它
1|1思路:先找到最小值,再替换
copybool DelMin(sqlList &L,Elemtype &value){
if(L.length == 0)return false;
int min = L.data[0];
int index = 0;
for(int i=1; i<L.length; i++){
if(L.data[i] < min){
min = L.data[i];
index = i;
}
}
L.data[index] = L.data[L.length-1];
L.length--;
return true;
}
2|02.顺序表逆序
2|1思路:前后调换
copyvoid Rever(sqlList &L){
int i=0;
int j=L.length-1;
for(int i=0; i<L.length/2; i++){
int t = L.data[i];
L.data[i] = L.data[j];
L.data[j] = t;
}
}
3|03.删除顺序表中所有特定值的元素
3|1要求:时间复杂O(n),空间复杂O(1)
3|2思路:在原数组上操作
copyvoid DelX(sqlList &L,int x){
int k=0;
for(int i=0; i<L.length; i++){
if(L.data[i] != x){
L.data[k] = L.data[i]; //相当于数组只存储除了x以为的数字,忽略x
k++; //新的长度递增
}
L.length = k;
}
}
4|04.删除有序表在s、t之间的所有数值,s
4|1思路:找到两边的边界,然后前移
copyvoide Del_S_T(sqlList &L,int s,int t){
if(s>=t || L.length==0)return false;
int i,j;
for(int i=0; i<L.length && L.data<s; i++){ //找到第一个大于等于S的值
if(i > L.length)return false;
}
for(int j=0; j<L.length && L.data<=t; j++){ //找到第一个大于t的值
if(j > L.length)return false;
}
for(; j<L.length; j++,i++){
L.data[i] = L.data[j]; //将s到t的数值进行覆盖(前移)
}
L.length = i; //当前i的值就是数组的长度
}
5|05.在顺序表中删除给定值s到t之间左右元素
5|1思路和第四题类似,但是注意这个没有说有序哦!
copyvoide Del_S_T(sqlList &L,int s,int t){
int k=0; //用于记录s到t中的元素的个数
for(int i=0; i<L.length; i++){
if(L.data[i]>=s && L.data[i]<=t){
k++; //说明在这个范围内
}else{
L.data[i-k] = L.data[i]; //当前元素移动K个位置
}
L.length -= k; //除去s-t之间的元素,就是删除后的数组长度
}
}
6|06.删除有序表中重复元素。
6|1维护不重复序列,将不重复的数字查到序列后方
copyvoide Del_S_T(sqlList &L,int s,int t){
for(int 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;
}
}
7|07.合并两个表
7|1思路:谁小先存谁
copysqlList Del_S_T(sqlList a,sqlList b,sqlList &c){
int i=0,j=0,k=0; //分别为a b c当前的下表
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;
return c;
}
8|08.将一维数组前m和后n个元素对调
8|1思路:先整体对调,再分别对小部分进行对调
copy//1 2 3 4 5 6 7 8
//8 7 6 5 4 3 2 1
//5 6 7 8 1 2 3 4
void Rever(SqList &L,int a,int b){
int t;
for(int i=0; i<(b-a+1)/2; i++){
t = L.data[a-1+i];
L.data[a-1+i] = L.data[b-1-i];
L.data[b-1-i] = t
}
}
void ans(SqList &L,int m,int n){
Rever(L,1,m+n); //换句话说 就是将AB求逆
Rever(L,1,n); //将A单独求逆
Rever(L,n+1,m+n); //将B单独求逆
}
9|09.有序表查找x,成功则与后一位数字交换位置;失败则插入x后依旧保持有序。
9|1要求:最少时间。
9|2思路:折半查找,找到则交换,找不到则插入x
copyvoid SerExcIns(int a[],int x){ //典型折半查找模板
int low=0,high=n-1,mid;
while(low <= high){
mid = (low+high)/2; //找到中间位置
if(a[mid] = x){
break;
}else if(a[mid] < x){
low = mid+1; //到右半部分找
}else{
high = mid-1; //到做半部分找
}
}
if(a[mid] == x && mid != n-1){ //查找成功并且不在最后
int t = a[mid];
a[mid] = a[mid+1];
a[mid+1] = t;
}
if(low > high){ //查找失败
for(int i=n-1; i>high; i--){
a[i+1] = a[i]; //一直后移
}
a[i+1] = x; //插入x
}
}
10|010.将表向左循环q个单位
10|1思路:与第八题相同
copyvoid Rever(SqList &L,int a,int b){
int t;
for(int i=0; i<(b-a+1)/2; i++){
t = L.data[a-1+i];
L.data[a-1+i] = L.data[b-1-i];
L.data[b-1-i] = t
}
}
void ans(SqList &L,int s,int w){
Rever(L,1,s); //将 前s个求逆
Rever(L,s+1,w); //将 前s+1到w求逆
Rever(L,1,w); //将 全部求逆
}
11|011.求两个等长升序表的中位数
11|1要求 时间和空间高效
11|2二路归并,依次遍历找小的元素,找到索引为一个序列长度的时候,那么此时就是中位数
copyint SearBiNum(int a[],int b[],int len){
int i=0,j=0,index=0;
while(i<len && j<len){
index++; //index表示当前遍历的元素下标
if(a[i] < b[j]){
i++; //第一个序列往前走
if(index == len){ //下标到了一个序列的长度那么此索引对应的元素必为中位数
return a[i-1];
}
}else{
j++; //第二个序列往前走
if(index == len){
return b[j-1];
}
}
}
}
12|012.求表的众数(找出一个元素大于数组长度的一半)
12|1思路:另外开辟一个新的数组,出现过的数字进行标记
copyint SearMain(int a[]){
int ans[a.length];
memset(ans, 0, sizeof(ans)); //默认都是0
for(int i=0; i<a.length; i++){
ans[a[i]]++; //用数组标记出现过的元素,在目标数组进行标记
}
for(int i=0; i<ans.length; i++){
if(ans[i] > a.length/2)return i; //返回下标就是主元素
}
return -1; //上面循环如果没有返回,则返回-1
}
13|013.求表中未出现的最小正整数
13|1思路:仍然使用数组标记,出现的数字置为1,再重新遍历新的数组
copyint FindLost(int a[],int n){
int ans[n];
memset(ans, 0, sizeof(ans)); //默认都是0
for(int i=0; i<n; i++){
if(a[i]>0 && a[i]<=n){
ans[a[i]-1] = 1; //若 A[i]的值介于1~n,则标记数组置为1
}
}
for(int i=0; i<n; i++){
if(ans[i] == 0) break; //没出现过
}
return i+1; //返回数组下标+1就是未出现的值
}
线性表完美撒花
__EOF__
作 者:xiaoff
出 处:https://www.cnblogs.com/xiaofff/p/13039736.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
由于时间有限,写的不好请见谅,理解万岁(:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· 本地部署 DeepSeek:小白也能轻松搞定!
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!
· Tinyfox 简易教程-1:Hello World!