1、有序顺序表的插入
题目:一个递增有序的顺序表L中数据元素为整型,设计一个时间和空间上都尽可能高效的算法,向L插入一个元素后,使得L仍然有序。
void ListInsert_Sq(SqList *L,int item){ //item为插入元素的值
if (L->size==L->len)
{
int *newbase = (int *)realloc(L->elem,(LISTINCREMENT + L->size) * sizeof(int));
if (!newbase) exit(-1);
L->elem = newbase;
L->size += LISTINCREMENT;
}
int i; //记录插入位置
for (i=0;i<L->len;i++)
if (L->elem[i]>item)
break;
for (int j=L->len;j>i;j--) //第i个及以后的元素后移
L->elem[j] = L->elem[j-1];
L->elem[i] = item;
L->len++;
}
2、顺序表的删除
(1)删除给定值的元素
题目:已知长度为n的有序线性表A采用顺序存储结构,设计一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。
void ListDelete_Sq(SqList *A,int item){
int *p = &(A->elem[0]);
int *q = &(A->elem[0]); //遍历A
int countq=0; //记录q是否跑出去即越界
int countp=0; //记录新顺序表的长度
while (q)
{
while (*q==item&&countq<A->len) //(连续)出现且未越界
{
q++;
countq++;
}
if (countq>=A->len) //越界
break;
*p = *q;
q++;
p++;
countq++;
countp++;
}
A->len = countp; //舍弃p到q(含pq)间的值
}
优化:直接用数组的移动代替指针的移动,数组的下标代替count,减少声明的变量和代码空间。
void ListDelete_Sq(SqList &L,int item)
{
int j = 0; //记录新顺序表的长度
for(int i=0; i<L.length;i++) //i遍历顺序表
{
if(L.elem[i] != item)
{
L.elem[j] = L.elem[i];
j++;
}
}
L.length = j;
}
(2)删除给定范围值的元素
题目:设计一个时间和空间上都尽可能高效的算法,从顺序表中删除其值在给定值s与t之间(包含s和t,要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示出错信息并退出运行。
void ListDelete_Sq(SqList *L,int s,int t){
if (s==t)
{
printf("s和t不应该相等!");
return;
}
if (s>t)
{
printf("s应该比t小!");
return;
}
if (L->len==0)
{
printf("顺序表为空!");
return;
}
//与上一题相同
int j = 0; //记录新顺序表的长度
for(int i=0; i<L.length;i++)
{
if(L.elem[i]<s || L.elem[i]>t)
{
L.elem[j] = L.elem[i];
j++;
}
}
L.length = j;
}