数据结构编程题总结
线性表
顺序表-查找
定义函数findx,传入要被查找的顺序表和要查找的值,如果找到返回值的索引,不存在则返回-1,并输出"不存在"
int findX(SqlList L,int val){ //传⼊的形参,因为并不
需要改变顺序表中的值,所以不⽤传⼊引⽤
//如果值是在顺序表中,则该函数就会在for循环内返回,就结束
//如果出了循环那就说明传⼊的值并不在顺序表中,所以输出"不
存在"并返回-1即可
for(int i=0;i< L.length;i++){
if(L.data[i] == val){
return i;
}
}
cout<<"不存在"<<endl;
return -1;
}
顺序表-插⼊元素
⼀⾮递减有序的顺序表arr,现插⼊元素x,写⼀函数保证arr仍然⾮递减有序
算法思想:
先找到要插⼊的位置,使 arr.data[i] < x <arr.data[i+1] ,确定val应该插⼊到索引为i的位置然后把i后⾯的元素后移,最后插⼊x , length++这样⼀来就是两个for循环
search(SqlList L, int val)
{ // 传⼊的形参,因为并不需要
改变顺序表中的值,所以不⽤传⼊引⽤
// 找到L.data[i] > val,就返回i
// 找不到,说明整个数组都⽐val⼩,把val插到末尾
for (int i = 0; i < L.length; i++)
{
if (L.data[i] > val)
{
return i;
}
}
return L.length;
}
void insert1(SqlList &L, int val)
{
int index = search(L, val);
for (int j = L.length - 1; j >= index; j--)
{
L.data[j + 1] = L.data[j];
}
L.data[i] = val; // 插⼊找到的索引位置
L.length++; // 别忘了⻓度加1
}
顺序表-删除元素
设计⼀个算法,从⼀给定的顺序表 L 中删除⼀个表中的元素x时间复杂度为O(n)、空间复杂度为O(1)的算法
算法思想:
从前往后遍历,把不等于x的值,放到顺序表中
void delx(Sqlist &L, Elemtype x)
{
int k = 0; // 记录值不等于x的元素的个数,就是要留下的元
素。
for (i = 0; i < L.length; i++)
if (L.data[i] != x)
{
L.data[k] = L.data[i]; // 下标对的元素值不等于x值
就留下
k++; // 不等于x的元素⾃增1
}
L.length = k; // 顺序表⻓度L等于k
}
顺序表-删除区间元素
设计⼀个算法,从⼀给定的顺序表 L 中删除下标 i~j(i<=j,包括 i 和 j)的所有元素
假定 i 和 j 都是合法的。
例如[11, 22, 33, 44, 55, 66, 77, 88, 99] 删除 [3, 6]之间的所有元素之后,
完整的顺序表是 [11, 22, 33, 88, 99, 66, 77, 88,99]
算法思想:
之前的删除顺序表元素操作,只是删除⼀个元素。⽽本题要求删除多个,只需要通过循环来完成即可。
void deleteScope(SeqList *L, int i, int j)
{
// [i, j]之间所有元素的个数,即要被删除的元素个数
int scope = j - i + 1;
// 将下标为 j 之后的所有元素向前移动 j-i+1 位,需要移
动 length - j - 1 次 for (int m = j + 1; m < L.length; m++)
{
L.data[m - scope] = L.data[m]; // ⽤后⾯的数
覆盖前⾯的数
}
// 修改顺序表表⻓
list.length = list.length - scope;
}
顺序表-元素逆置
设计⼀个⾼效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
算法思想:
扫描顺序表L的前半部分元素,对于元素L.data[i]和其后半部分对应元素L.data[L.length-i-1]进⾏交换
void Reverse(SeqList &L)
{
int temp; // 交换中介
for (int i = 0; i < L.length / 2; i++)
{
temp = L.data[i];
L.data[i] = L.data[L.length - i - 1];
L.data[L.length - i - 1] = temp;
}
}
顺序表-两递增顺序表求交集
假设现在⽤两个递增有序的顺序表L1和L2存储集合A和B,求这两个集合的交集 得到新的顺序表L3
算法思想:
- 要得到的是交集,也就是两个顺序表中重复的元素
- 依次⽐较L1和L2中的相应元素,若相等,该元素副本进⼊L3,i ,j都往后移动;否则,较⼩元素所在的表下标后移。某个表搜索结束则循环结束,交集元素存在于L3表。
void merge(SeqList &A, SeqList &B, SeqList &C)
{
int i = 0;
int j = 0;
int k = 0;
while (i < A.length && j < B.length)
{
if (A.data[i] < B.data[j])
i++;
else if (A.data[i] > B.data[j])
j++;
else if (A.data[i] == B.data[j])
{ // 如果相等则存
⼊到新的顺序表l3中
C.data[k++] = A.data[i++];
j++;
}
}
C.length = k;
}
顺序表-求两个递增序列合并后的中位数
设 A 和 B 是两个存放整型元素的 递增有序顺序表, 将他们合并为⼀个新的递增序列后,求其中位数(个数为偶数时为左半部分的最后⼀个数)
算法思想:
- 按递增顺序合并到C
- 取出(L1.length+L2.length-1)/2的位置的值
int findMid(SeqList &A, SeqList &B, SeqList &C)
{
int k = 0, i = 0, j = 0;
while (i < A.length && j < B.length)
{
if (A.data[i] <= B.data[j])
{
C.data[k++] = A.data[i++];
}
else
{
C.data[k++] = B.data[j++];
}
}
while (i < A.length)
C.data[k++] =
A.data[i++];
while (j < B.length)
C.data[k++] =
B.data[j++];
return C.data[(n + m - 1) / 2]
}
时间复杂度:\(O(n)\)
空间复杂度:\(O(n)\)

浙公网安备 33010602011771号