834数据结构 顺序表考纲要求:
- 线性表的顺序存储结构:静态分配,动态分配
- 顺序表的插入删除算法,移动元素次数分析
- 顺序存储结构的优缺点,引出单链表的结构类型定义
1、顺序表采用数组存储元素,静态数组需先指定大小,但也可以动态的分配数组的大小(通过指针来”追踪“数组中的元素),用malloc分配初始空间,用realloc分配后期扩容的空间
2、顺序表的插入算法:
在表L的第i个位置上插入新的元素e,若i值不正确,则返回0,否则将第i个元素及以后的元素 均后移 一个位置,空出一个位插入,表长增1(总结为:判--移--添)
int ListInsert(SqList &L,ElemType e,int i)
{
int j;
if(i<1||i>L.length+1)
{
return 0;
}
i--; //将逻辑位转换位 数组下标
for(j=L.length;j>i;j--)
{
L.data[j]=L.data[j-1];
}
L.data[i]=e;
L.length++;
return 1;
}
3、顺序表的删除算法:
删除第i个元素,若i值不正确,则返回0。否则,将第i个元素的之后的元素 均向前移动一个位置,覆盖待删除元素,表长减一(总结为:判断---覆盖--)
int ListInsert(SqList &L,ElemType e,int i)
{
int j;
if(i<1||i>L.length+1)
{
return 0;
}
i--; //将逻辑位转换位 数组下标
e=L.data[i];
for(j=i;j<L.length-1;j--) //注意j的范围
{
L.data[j]=L.data[j+1];
}
L.length--;
return 1;
}
4、顺序表的优缺点:
优:无需为元素间的逻辑关系而增加额外的空间,可以随机存取,存储密度大(=1),存储空间利用率高
缺:要求占用一整片连续的空间,且插入和删除元素时需移动大量元素(效率底,不方便),如:在个元素的顺序表中插入一个元素,需平均移动个元素,删除一个元素,需平均移动个元素
5、设计一个高效算法,将顺序表的所有元素逆置,且算法空间复杂度为O(1)
答:遍历顺序表的前半元素,将其与后半元素一一进行交换,算法时间复杂度O(n)
void reverse(SqList &L)
{
int i;
ElemType x;
for(i=0;i<L.length/2;i++)
{
x=L.data[i];
L.data[i]=L.data[L.length-i-1];
L.data[L.length-i-1]=x;
}
}
6、将n个整数存放到一维数组R中,设计一个高效算法,将R中的整数序列循环左移p个位置(0<p<n)
答:先将n个元素的序列整体逆置,再将所得序列 的前n-p个元素与 后p个元素分别逆置,得到最终结果
void reverse(int R[],int left,int right)
{
int k=left,j=right,tmp;
while(k<j)
{
//交换,逆置
tmp=R[k];
R[k]=R[j];
R[j]=tmp;
k++;
j--;
}
}
void leftShift(int R[],int n,int p)
{
if(p>0&&p<n)
{
reverse(R,0,n-1); //将全部元素逆置
reverse(R,0,n-p-1); //将前n-p个元素逆置
reverse(R,n-p,n-1); //将后p个元素逆置
}
}
7、设顺序表A中前m个元素递增有序,后n个元素递增有序,设计算法使得整个表A递增有序,要求空间复杂度为O(1)
答:思路--空间复杂度限制故不可新建顺序表,将A中的后半部分插入到前半部分中即可实现,且表长度不变
void merge1(Sqlist &A,int m,int n)
{
int i=0,j=m,k;
Elemtype tmp; //与表元素同类型的变量
while(j<A.length&&i<j)
{
if(A.data[j]>A.data[j-1]) //整个表已递增有序
break;
else if (A.data[j]<A.data[i])
{
tmp=A.data[j];
for(k=j-1;k>=i;k--) //将A.data[i]及之后的元素后移
A.data[k+1]=A.data[k];
A.data[i]=tmp;
i++;
j++;
}
else
i++; //直到找到比j所在元素大的元素
}
}
8、两个顺序表A,B,元素个数分别为m、n,都是递增有序,现将两者合并为一个顺序表B,其中B的存储空间足够大,要求不开辟其他表空间
答:将A中的较小元素依次插入到B中即可
void merge2(Sqlist &A,Sqlist &B)
{
int i=0,j=0,k;
while(i<A.length)
{
if(A.data[i]>B.data[B.length-1])
{
B.data[B.length]=A.data[i];
B.length++;
i++;
}
else if(A.data[i]<B.data[j]) //要将A.data[i]插入到B.data[j]处
{
for(k=B.length-1;k>=jk--)
{
B.data[k+1]=B.data[k]; //后移B.data[j]及其之后的元素
}
B.data[j]=A.data[i];
B.length++;
i++;
j++;
}
else
j++;
}
}