《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,表示程序执行结束 }