倒置顺序表
已知数组中存放了两个线性表(a1,a2,a3....am)和(b1,b2,b3......bn),设计一个算法,用尽可能少的辅助空间将两个线性表的位置互换。
(1)、线性表位置互换一:
从b1开始的把b表的所有元素都插入到a表之前,首先将b表的元素bi存储到一个临时变量temp中,然后将a表的所有元素后移一位,其次将temp插入到腾出来的位置上,此时只需要一个临时的辅助空间。
1 2 3 4 5 6 7 8 9 10 11 12 | void Exchange1(SeqList L, int m, int n) { int i,j; ElemType temp; for (i=0;i<n;i++) { temp=L.elem[m+i+1]; //第二个表的第一个位置,加1是因为要跳过设置的间隔符0 for (j=m+i-1;j>=i;j--) //注意,这里并不是把所有的元素后移,而是在拷贝的数字这里结束 L.elem[j+1]=L.elem[j]; L.elem[i]=temp; } } |
此时时间复杂度为:O(m*n),空间复杂度为O(1);
(2)、第二种交换方法: 将整个线性表的元素倒置,如a1a2a3....an b1b2b3...bn,变为b1b2b3...bn a1a2...an,然后再分别将第一个表和第二个表倒置即可,即执行三次倒置。
1 2 3 4 5 6 7 8 9 10 11 12 | //元素倒置 void invert(SeqList *s, int m, int n) { ElemType temp; int i; for (i=m;i<(m+n+1)/2;i++) { temp=s->elem[i]; s->elem[i]=s->elem[m+n-i]; s->elem[m+n-i]=temp; } } |
其中倒置算法的时间复杂度为O((m+1-n)/2)。
开始倒置顺序表
1 2 3 4 5 6 7 8 9 10 | void Exchange2(SeqList *s, int m, int n) { int i; //将全表倒置 invert(s,0,m+n); //将第一个表倒置 invert(s,0,n-1); //第二个表倒置 invert(s,n+1,m+n); } |
整个算法的时间复杂度为O((m+n+1)/2+(n-1+1)/2+[(m+n)+1-n]/2)=O(m+n),空间复杂度为O(1)。
源程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | #include<stdio.h> #include<stdlib.h> #include<iostream> using namespace std; #define MAXSIZE 100 #define ElemType int //定义结构体 typedef struct { ElemType elem[100]; int length; }SeqList; //顺序表的初始化 SeqList Init_Seq(){ SeqList L; L.length=0; return L; } //顺序表的建立 SeqList Create_Seq(SeqList L) { ElemType x; scanf ( "%d" ,&x); while (x!=-1) { L.elem[L.length]=x; L.length++; scanf ( "%x" ,&x); } return L; } /*线性表位置互换一:从b1开始的把b表的所有元素都插入到a表之前, 首先将b表的元素bi存储到一个临时变量temp中,然后将a表的所有元素后移一位, 其次将temp插入到腾出来的位置上,此时只需要一个临时的辅助空间 */ void Exchange1(SeqList L, int m, int n) { int i,j; ElemType temp; for (i=0;i<n;i++) { temp=L.elem[m+i+1]; //第二个表的第一个位置,加1是因为要跳过设置的间隔符0 for (j=m+i-1;j>=i;j--) //注意,这里并不是把所有的元素后移,而是在拷贝的数字这里结束 L.elem[j+1]=L.elem[j]; L.elem[i]=temp; } printf ( "交换之后线性表的元素为:\n" ); for (i=0;i<n;i++) printf ( "%d " ,L.elem[i]); for (i=n;i<L.length-1;i++) printf ( "%d " ,L.elem[i]); printf ( "\n********************\n" ); } /* 第二种交换方法: 将整个线性表的元素倒置,如a1a2a3....anb1b2b3...bn,变为b1b2b3...bna1a2...an 然后分别将第一个表和第二个表倒置即可 */ //元素倒置 void invert(SeqList *s, int m, int n) { ElemType temp; int i; for (i=m;i<(m+n+1)/2;i++) { temp=s->elem[i]; s->elem[i]=s->elem[m+n-i]; s->elem[m+n-i]=temp; } } void Exchange2(SeqList *s, int m, int n) { int i; //将全表倒置 invert(s,0,m+n); //将第一个表倒置 invert(s,0,n-1); //第二个表倒置 invert(s,n+1,m+n); printf ( "第二种倒置方法交换后如下:\n" ); for (i=0;i<n;i++) printf ( "%d " ,s->elem[i]); for (i=n+1;i<s->length;i++) printf ( "%d " ,s->elem[i]); printf ( "\n********************\n" ); } void main() { SeqList seqlist,*p; int i,middle; //ElemType x; seqlist=Init_Seq(); printf ( "创建一个顺序表的顺序,其中两个顺序表表以0作为间隔符,以-1作为结束符:\n" ); seqlist=Create_Seq(seqlist); p=&seqlist; for (i=0;i<p->length;i++) if (p->elem[i]==0) middle=i; printf ( "您所创建的顺序表如下:\n" ); for (i=0;i<middle;i++) printf ( "%d " ,seqlist.elem[i]); for (i=middle+1;i<seqlist.length;i++) printf ( "%d " ,seqlist.elem[i]); printf ( "\n执行第一种倒置后的变为:\n" ); Exchange1(seqlist,middle,seqlist.length-middle-1); Exchange2(p,middle,seqlist.length-middle-1); } |
效果如图:
很希望自己是一棵树,守静、向光、安然,敏感的神经末梢,触着流云和微风,窃窃的欢喜。脚下踩着最卑贱的泥,很踏实。还有,每一天都在隐秘成长。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步