数据结构编程题总结

线性表

顺序表-查找

定义函数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

算法思想:

  1. 要得到的是交集,也就是两个顺序表中重复的元素
  2. 依次⽐较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 是两个存放整型元素的 递增有序顺序表, 将他们合并为⼀个新的递增序列后,求其中位数(个数为偶数时为左半部分的最后⼀个数)

算法思想:

  1. 按递增顺序合并到C
  2. 取出(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)\)

posted @ 2023-06-25 08:28  Wmic  阅读(62)  评论(0)    收藏  举报