潭影-pjq

《2023数据结构考研复习指导(王道)》——关于部分练习题的一些思考(2.2.3)

一、选择题

1.顺序表(逻辑上相邻的元素物理上也相邻),其占用的存储空间与元素存放顺序无关

优点 缺点
①存储密度大 ①插入删除操作比较复杂(时间复杂度均为O(n))
②方便随机存取 ②改变容量不方便,容易产生碎片

2.在一个长度为n的顺序表中删除第i(1<=i<=n)个元素,需要向前移动n-i个元素

解析:删除第i的元素,相当于第i个元素之后的所有元素都要前移,显然第i个元素之后的元素个数是(n-i)个

3.若长度为n的非空线性表采用顺序存储结构,在表的第i个位置插入一个元素,则i的合法值是1<=i<n+1

解析:i≥1,很容易理解;之所以i≤n+1,是因为i有可能插入在最后一个元素的下一个位置,即n+1

二、综合应用题

直接上code(本人使用的Visual Stdio2019)

//这一段代码写好之后可将其放在头文件里,命名为function.h
#define _CRT_SECURE_NO_WARNINGS   //解决VS2019的scanf编译报错问题
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxSize 50
typedef int ElemType;
typedef struct {
    ElemType data[MaxSize]; //用静态数组实现线性表
    int length;             //定义线性表当前长度
}SqList;
//初始化顺序表
bool InitList(SqList& L)
{
    for (int i = 0; i < MaxSize; i++)
        L.data[i] = 0;
    L.length = 0;
    return true;
}
//向顺序表中插入元素
bool InsertList(SqList& L, int i, ElemType e)
{
    if (i<1 || i>MaxSize)
        return false;
    if (i > L.length + 1)
        return false;
    for (int j = L.length; j > i; j--)
    {
        L.data[j] = L.data[j - 1];
    }
    L.data[i - 1] = e;
    L.length++;
    return true;
}
//删除顺序表中的元素并带回
bool DeleteList(SqList& L, int i, ElemType& e)
{
    if (i<1 || i>MaxSize)
        return false;
    if (i > L.length)
        return false;
    e = L.data[i - 1];
    for (int j = i; j < L.length; j++)
    {
        L.data[j - 1] = L.data[j];
    }
    L.length--;
    return true;
}
//打印顺序表中元素
void PrintList(SqList L)
{
    for (int j = 0; j < L.length; j++)
    {
        printf("%3d", L.data[j]);
    }
    printf("\n");
}

#pragma once//这个东西是编译器自己生成的,暂时不明白其用途

下面是一些部分应用题(01,03)的代码

#include"function.h"
//01.从顺序表中删除最小的元素(假设其唯一)并返回其值,空出的位置由顺序表的最后一位元素填补
//——如顺序表为空,则显示错误信息并退出运行
//?思考
//(1)我们可以假设顺序表中第一个元素最小
//——第一个元素与第二个元素对比,若真,则返回第一个元素;假,返回第二个元素(“真”是指第一个元素最小)
//依次将返回的比较小的元素与后续元素对比,删除最小并填充
//——这个是书上给的解法,和冒泡排序有些相似;我想自己写一个函数解决这个问题,用快速排序(暂时搁置,我还没有理解快排)
//———————————————————————————————————————————————————————————————————————————————————————————————————————
//03.对于长度为n的顺序表,编写一个T(n)=O(n),S(n)=O(1)的算法,删除线性表所有值为m的函数
// ?思考
// 03(1)我们可以定义一个k,用于记录!=m的个数,将!=m的元素移动到数组下标为k的位置,更新k值
// 扫描结束后修改L的长度
// 03(2)我们可以定义一个k,用于记录=m的个数,并将!=m的元素前移k个位置,更新k值
// 修改完成后修改L的长度
// 03(3)我们可以映射一个数组,将!=k的元素填入其中,返回映射的数组
//———————————————————————————————————————————————————————————————————————————————————————————————————————
//01.删除最小的元素
bool Delete_Min(SqList& L, ElemType& min_value) //01
{
    int pos = 0;
    min_value = L.data[pos];//先假设第一个元素最小
    for (int i = 1; i < L.length; i++)//初试设置i=1,意在第一个元素与第二个元素比较
    {
        if (L.data[pos] > L.data[i])//如果第一个元素>第二个元素
        {
            min_value = L.data[i];//则将第二个元素的值赋给min_value
            pos = i;              //将pos设置为i,回到循环,让第二个元素与第三个元素比较,依此类推
        }
    }
    L.data[pos] = L.data[L.length - 1];
    L.length--;
    return true;
}
//01推广.取得最小的元素
bool Get_Min(SqList& L, ElemType& min_value) //01的推广,取得顺序表中的虽小的元素
{
    int pos = 0;
    min_value = L.data[pos];//先假设第一个元素最小
    for (int i = 1; i < L.length; i++)//初试设置i=1,意在第一个元素与第二个元素比较
    {
        if (L.data[pos] > L.data[i])//如果第一个元素>第二个元素
        {
            min_value = L.data[i];//则将第二个元素的值赋给min_value
            pos = i;              //将pos设置为i,回到循环,让第二个元素与第三个元素比较,依此类推
        }
    }                             //删掉修改元素即表长的两句就行了
    return true;
}
//03.删除相同元素
ElemType Delete_Same_Element(SqList& L, ElemType m)
{
    int k = 0;//用于记录不等于m的元素的个数
    int i;//用于扫描顺序表
    for (i = 0; i < L.length; i++)
    {
        if (L.data[i] != m)
        {
            L.data[k] = L.data[i];
            k++;
        }
    }
    L.length = k;
    return k;
}
//03第二个方法.删除相同元素
ElemType Delete_same_Element_second(SqList& L, ElemType m)
{
    int k = 0;//用于记录=m的元素的个数
    int i;//用于扫描顺序表
    for (i = 0; i < L.length; i++)
    {
        if (L.data[i] == m)
        {
            k++;
        }
        else
        {
            L.data[i - k] = L.data[i];
        }
    }
    L.length = L.length - k;
    return k;
}
//03第三个方法.删除相同元素
SqList Delete_same_elem(SqList& L, ElemType m, SqList L_mapping)//mapping是映射的意思
{
    int i;//用于扫描数组L
    int k = 0;//用于在映射数组中填入数据
    for (i = 0; i < L.length; i++)
    {
        if (L.data[i] != m)          //如果数组元素!=m,就将元素填入映射数组中
        {
            L_mapping.data[k] = L.data[i];
            k++;
        }
    }
    L_mapping.length = k;
    return L_mapping;
}
int main()
{
    SqList L;
    ElemType x;
    ElemType m = 12;
    SqList L_mapping;
    InitList(L);
    InitList(L_mapping);
    bool ret;
    InsertList(L, 1, 23);
    InsertList(L, 2, 12);
    InsertList(L, 3, 45);
    InsertList(L, 4, 34);
    InsertList(L, 5, 56);
    PrintList(L);
    ret=Delete_Min(L, x);
    if (ret)
        printf("最小值元素:%d\n", x);
    else
        printf("找不到\n");
    PrintList(L);
    //Delete_Same_Element(L, 45);
    //Delete_same_Element_second(L, 45);
    L_mapping=Delete_same_elem(L, 45, L_mapping);
    PrintList(L);
    PrintList(L_mapping);

    return 0;//主函数里要记得加上这个return 0,表示程序执行结束
}

 

           

posted on 2022-04-28 18:18  潭影-pjq  阅读(518)  评论(0编辑  收藏  举报