文章目录
- 题目一
- 分析
- 思路一
- 思路二
- 代码实现
- 效果
- 题目二
- 分析
- 代码实现
- 效果
题目一
从有序顺序表中删除所有其值重复的元素,使所有元素的值都不相同。
分析
思路一
- 首先,在有序顺序表中,所有值重复的元素相邻。为此,我们只需顺序访问顺序表中的元素,并查找出值重复的元素并删除。
- 因此,我们可以设置二维变量数组buzz记录重复元素个数,遍历到当前元素时,将当前元素与后一元素比较,若相同,buzz值加一。若不同,加入下一元素的重复个数。
- 最后,再将buzz数组中的元素读入原顺序表,即可完成题目要求。此算法时间复杂度为O(n),空间复杂度为O(n)。
思路二
- 根据有序顺序表的特性,我们可以考虑利用直接插入排序的思想,将第零个元素作为不重复元素,后续元素与前面元素比较,若值不同,则插入顺序表,并更新不重复元素比较基准值为当前元素。时间复杂度为O(n),空间复杂度为O(1)。
代码实现
下面仅实现思路二的代码
int LinearList::Question_06()
{
if(arr.length <= 0)
return -1;
int i = 0,j = 1;
for(i = 0,j= 1;j < arr.length;j ++)
{
if(arr.data[j] != arr.data[i])
arr.data[++i] = arr.data[j];
}
arr.length = i + 1;
return 0;
}
效果
题目二
线性表(a1,a2,a3…,an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置互换。反之,则将其插入表中使表中元素仍然递增有序。
分析
- 题目涉及到元素查找且要求时间最短,可以考虑折半查找的算法思想:将线性表一分为二,将key值与中间元素比较。若相等,则查找成功。若不等,则该元素必然在线性表的左区间或者右区间中。再重复上述步骤,当区间长度等于1(查找失败)或者查找成功,则推出算法。
- 若查找成功,则将该元素与后一元素互换。若查找失败,则在刚刚最后查找位置插入key值,即可完成题目要求。时间复杂度为O(log2n),空间复杂度为O(1)。
代码实现
Array LinearList::Question_09(int x)
{
int key = x;
//折半查找key
int left = 0,right = arr.length-1,mid = 0;
while(left <= right)
{
mid = (left+right)/2;
cout<<"mid: "<<mid<<endl;
if(arr.data[mid] == key)//若查找成功
{
int temp = arr.data[mid];
arr.data[mid] = arr.data[mid+1];
arr.data[mid+1] = temp;
return arr;
}
if(arr.data[mid] > key)//key可能在左半区间
{
right = mid-1;
}
else if(arr.data[mid] < key)//key可能在右半区间
{
left = mid+1;
}
}
//查找失败
arr.length ++;
for(int i = arr.length-1;i > left;i --)
{
arr.data[i] = arr.data[i-1];
}
arr.data[left] = key;
return arr;
}