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++;
}
}