Alpha
1.请编写一个程序,完善函数PrintList
,实现创建一个顺序表,并实现打印顺序表的功能。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int length;
}SqList;
void PrintList(SqList L){
//请在此处编写代码
}
int main(){
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
PrintList(L);
return 0;
}
for(int i=0;i<L.length;i++){
printf("%d\n",L.data[i]);
}
根据已知代码可以发现数组内容已经排好序了 ,所以只需要将他们按照数组下标打印出来即可
2.请编写一个程序,完善函数ListInsert
和PrintList
,实现在顺序表中的指定位置插入元素的功能,并打印输出顺序表
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
} SqList;
bool ListInsert(SqList *L, int i, ElemType e) {
//请在此处编写代码
}
void PrintList(SqList L) {
//请在此处编写代码
}
int main() {
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
bool ret = ListInsert(&L, 2, 4);
if (ret) {
printf("Insert success\n");
PrintList(L);
} else {
printf("Insert is false\n");
}
return 0;
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
} SqList;
bool ListInsert(SqList* L, int i, ElemType e) {
//请在此处编写代码
if (i<1 || i>L->length + 1)
return false;
if (L->length >= MAXSIZE)
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;
}
void PrintList(SqList L) {
//请在此处编写代码
for (int i = 0; i < L.length; i++) {
printf("%d\n", L.data[i]);
}
}
int main() {
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
bool ret = ListInsert(&L, 2, 4);
if (ret) {
printf("Insert success\n");
PrintList(L);
}
else {
printf("Insert is false\n");
}
return 0;
}
关于结构体:
如果是结构体变量,用“.”
void func1(struct SeqList L) {
// L 是结构体变量(按值传递)
}
如果是结构体指针,用->
void func2(struct SeqList* L) {
// L 是结构体指针(按指针传递)
}
3.请编写一个程序,完善函数ListDelete
和PrintList
,实现在顺序表的指定位置删除元素的功能,并打印输出顺序表
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
} SqList;
bool ListDelete(SqList *L, int i, ElemType *e) {
//请在此处编写代码
}
void PrintList(SqList L) {
//请在此处编写代码
}
int main() {
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
ElemType e;
bool ret = ListDelete(&L, 2, &e);
if (ret) {
printf("Delete success\n");
PrintList(L);
} else {
printf("Delete is false\n");
}
return 0;
}
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
} SqList;
bool ListDelete(SqList* L, int i, ElemType* e) {
//请在此处编写代码
if (i < 1 || i>L->length)//L->length+1
return false;
if (L->length ==0)
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 i = 0; i < L.length; i++) {
printf("%d\n", L.data[i]);
}
}
int main() {
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
ElemType e;
bool ret = ListDelete(&L, 2, &e);
if (ret) {
printf("Delete success\n");
PrintList(L);
}
else {
printf("Delete is false\n");
}
return 0;
}
删除思路:
不在顺序表范围内无法进行删除;
将要删除的数据存储到e中,(将位置 i
的元素值(L->data[i - 1]
)存储到指针 e
指向的变量中。注意:i
是从1开始计数的,而数组索引从0开始,因此需要减1。)
然后通过循环将数据往前移一位,然后顺序表长度减一
Q:为什么不是length+1
A: 如果条件是 j < L->length + 1
,则循环会多执行一次,访问到 L->data[L->length]
,这超出了有效数据的范围(因为顺序表的有效元素个数是 L->length
,索引范围是 0
到 L->length - 1
)
Q:为什么要将需要删除的数据存储到e指向的变量中
A:数据备份,日志记录,后续处理,通过将被删除的元素值存储到指针 e
指向的变量中,可以方便地将这个值传递给调用者,而不需要在函数内部进行额外的返回值处理
4.请编写一个程序,完善函数LocateElem
,实现在顺序表中查找指定元素位置的功能,并打印输出顺序表。
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int length;
}SqList;
int LocateElem(SqList L, ElemType e){
//请在此处编写代码
}
int main(){
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
int ret = LocateElem(L, 2);
if(ret != -1){
printf("Locate success\n");
printf("Position: %d", ret);
} else{
printf("Locate is false\n");
}
return 0;
}
#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
}SqList;
int LocateElem(SqList L, ElemType e) {
//请在此处编写代码
for (int i = 0; i < L.length; i++) {
if (e == L.data[i])
return i + 1;
}
return -1;
}
int main() {
SqList L;
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
int ret = LocateElem(L, 2);
if (ret != -1) {
printf("Locate success\n");
printf("Position: %d", ret);
}
else {
printf("Locate is false\n");
}
return 0;
}
Q:为什么return A:如果找到了目标元素,返回其位置索引(正整数)。如果未找到目标元素,返回一个与有效位置索引不冲突的值。
-1
是一个负数,与任何有效的正整数位置索引都不冲突,因此它是一个非常合适的选择,用于明确表示“查找失败”。
第二部分:
1.以下说法错误的(D )。
- A. 求表长、定位这两种运算在采用顺序存储结构时实现的效率不比采用链式存储结构时实现的效率低
- B. 顺序存储的线性表可以随机存取
- C. 由于顺序存储要求连续的存储区域,所以在存储管理上不够灵活
- D. 线性表的链式存储结构优于顺序存储结构
顺序存储结构可以通过变量length来求表长,定位操作也可以直接索引来查找,时间复杂度为O(1),链式存储求表长需要遍历整个链表,时间复杂度为O(n),定位操作也需要遍历整个链表,时间复杂度是O(n)。
由于数据存储在连续的内存中,可以通过索引直接访问任意位置的元素,可以随机存取,链式存储无法随机存取,只能遍历
顺序存储的内存一开始是分配好的,想要改变需要重新分配内存并且复制数据,链式存储可以动态分配,不需要连续的内存空间,所以顺序存储在存储上不够灵活
2.对于双向链表,在两个结点之间插入一个新结点需修改的指针共____4_____个,单链表为___2_____个。
3.链表是采用链式存储结构的线性表,进行插入、删除操作时,在链表中比在顺序存储结构中效率高( √ )
4.线性表的特点是每个元素都有一个前驱和一个后继( × )
第一个元素没有前驱,最后一个元素没有后继
栈
只允许在一端进行插入删除
空栈
栈底:不允许插入和删除 栈底元素
栈顶:允许插入和删除 栈顶元素
后进先出
InitStack(&S) 初始化栈。创建一个空栈,分配内存空间
DestroyStack(&S)销毁栈并释放空间
Push(&s,x)进栈,s栈未满则x进入成为新栈顶
Pop(&s,&x)出栈,如果s不为空,则弹出新栈顶并用x返回 &x是引用符号
GetTop(s,&x)如果s不为空,则用x返回栈顶元素,但不会删除