1.已知一个长度为n的线性表a采用顺序存储结构,设计一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除表中所有值为x的数据元素
题目分析:
方法一:设删除a中所有值等于x元素后的顺序表为a1,显然a1属于a,所以a1可以再次使用a的存储空间;所以思路为:扫描顺序表a,重建a中只包含除x外的元素得到一个新的顺序表a1
如:
删除我们需要删除的元素后得到一个新的顺序表如下:
算法如下:
void delnodel(SqList*& a, ElemType x)
{
int k = 0, i; //k记录值不等于x的元素个数,所以初始值为0,i用来扫描表中的所有;元素
for (i = 0; i < a->length; i++)
{
if (a->data[i] != x) //如果当前元素不为x,则插入表a中,也就是新的表a1
{
a->data[k] = a->data[i]; //插入的第一个元素在新的表中的第一题个位置
k++; //k增加1,下一个元素的位置就插入的这里,依次类推,直到扫描完表中所有的元素
}
a->length = k; //改变新建表的长度
}
}
方法二:用k记录顺序表a中等于x的元素的个数,一边扫描a一边统计k的值,将不为x的元素前移k个位置,最后修改a的长度
同样的如图:
使用这个方法后的顺序表为:
对应的算法为:
void delnode2(SqList*& a, ElemType x)
{
int k = 0, i = 0; //k用来记录等于x的元素的个数
while (i<a->lenth) //依次扫描所有的元素
{
if (a->data[i] == x) //当前元素值为x时k增加1
{
k++;
}
else //当前元素不为x时将其前移k个位置,
{
a->data[i - k] == a->data[i];
i++;
}
}
a->length -= k; //新建的顺序表长度为length-k
}
2.设顺序表L中有10个整数,设计一个算法,以第一个元素为分界线,将所有小于等于第一个元素的元素移动到该元素的前面,将所有大于他的元素移动到该元素的后面
题目分析: 我们需要把第一元素x提取出来后,把剩下的所有元素和x进行比较<=x的放在前面,大于x的放在后面如图
方法1:
设置一个变量pivot用来存放第一个元素,设置一个变量i从前向后找>pivot的元素,设置一个变量j从后向前找<=pivot的元素,最后两者交换位置,再把取出来的元素放在i和j相遇的位置,算法结束
如图:
算法如下:
void move1(SqList*& L)
{
int i = 0, k = L -> length - 1; //i为第一个位置,j为最后一个位置
ElemType pivot = L->data[0]; //以data[0]为基准
while (i < j)
{
while (i<j&&L->data[j]>pivot)
{
j--; //从后向前扫描元素,依次找到每一个<=pivot的元素
}
while (i<j&&L->data[i]<=pivot)
{
i++; //从前向后扫描,依次找到每一个>pivot的元素
}
if (i < j) //交换找到后的两种不同的元素的位置
{
tmp = L->data[i];
L - data[i] = L->data[j];
L->data[i] = tmp;
}
}
tmp = L->data[0]; //最后将取出来的第一个元素放在L->data[j]的位置
L->data[0] = L->data[j];
L->data[j] = tmp;
}
方法2:
取出第一个元素后,先从后面找小于等于x的元素然后前移到第一个取出元素的位置,再前面向后找大于x的元素,放在从后面的元素的位置
算法:
void move2(SqList*& L)
{
int i = 0, j = L->length - 1; //一个从前,一个从后
ElemType pivot = L->data[0]; //以第一个元素为基准
while (i<j)
{
while (j>i&&L->data[j]>povit)
{
j--; //从右向左扫描,找一个<=pivot的data[j]
L->data[i] = L->data[j]; //将其放在data[i]处
}
while (i<j&&L->data[i]<=pivot)
{
i++;
}
}
L->data[i] = pivot; //放基准元素
}
注 例题来自:数据结构_中国大学MOOC(慕课) (icourse163.org)