【蓝蓝计算机考研算法】-day23-顺序表的删除最小&逆转&删除为x的元素

133 阅读2分钟

32、描述:删除顺序表中最小的元素,由最后一个元素补充。

思路

考虑顺序表中的元素是有序还是无序,若是有序,直接删除最小一个。
若是无序:可先排序,然后将最后一个元素替换最小值 以下代码是用查找最小值元素并记录其位置,搜索结束用最后一个元素覆盖最小值元素位置,顺序表长减一方式实现的。

具体实现

#include<stdio.h>

//静态分配方式定义顺序表结构体
#define MAXSIZE 100//最大长度
typedef struct {
    int data[MAXSIZE];//数据域
    int length; //顺序表当前的长度
}SqList;

//创建顺序表
bool CreatList(SqList& L, int n) {//创建有n个元素的顺序表
    if (n > MAXSIZE) return false; //不能超过顺序表的最大长度
    for (int i = 0; i < n; i++) {//输入n个元素的值
        scanf_s("%d", &L.data[i]);
    }
    L.length = n;//更新顺序表的长度
    return true;
}

//删除顺序表最小值
bool DeletdMin(SqList& L) {
    if (L.length == 0)//顺序表为空,返回false
        return false;
    int minPos = 0;//记录最小元素的下标
    for (int i = 0; i < L.length; i++) {
        if (L.data[i] < L.data[minPos]) {//当前元素小于最小值小标所在的元素,就更新
            minPos = i;
        }
    }
    L.data[minPos] = L.data[L.length - 1];//用最后一个元素覆盖最小值的位置
    L.length--;//顺序表长减一
    return true;
}

int main()
{
    SqList L;//初始化顺序表
    int n;
    printf("请输入顺序表的长度,不要超过最大长度:");
    scanf_s("%d", &n);
    printf("请输入%d个元素的值:",n);
    CreatList(L, n);//创建顺序表
    DeletdMin(L);//删除顺序表最小
    printf("删除最小元素后的顺序表为:");
    for (int i = 0; i < L.length; i++) {
        printf("%d ", L.data[i]);
    }
    printf("\n");
    return 0;
}

运行结果

image.png

复杂度

  • 时间复杂度 O(n)--- 遍历整个顺序表,其中n为当前顺序表长度
  • 空间复杂度 O(1)--- 顺序表为必要空间,其次仅含常数级的辅助空间

33、逆转顺序表中的元素

思路

将顺序表最后一个元素与第一个进行交换,交换到中间位置停止。
扫描顺序表前半部元素L.data[i] (0<=L.length/2),将其与后半段元素 L.data[L.length - i - 1]进行交换

具体实现

//顺序表逆置
#include<stdio.h>
#define MaxSize 100//顺序表最大长度
typedef struct	 {
	int data[MaxSize];
	int length;
}SqList;
	
//创建顺序表
bool CreatList(SqList& L,int n) {//创建含有n个元素的顺序表
	if (n > MaxSize) return false;
	for (int i = 0; i < n; i++) {//输入n个元素的值
		scanf_s("%d", &L.data[i]);
	}
	L.length = n;//更新表长为n的大小
	return 0;
}
// 顺序表逆置
void Reverse(SqList& 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[i] = L.data[L.length - i - 1];
		L.data[L.length - i - 1] = temp;
	}
}
int main() {
	SqList L;
	int n;//创建顺序表的长度
	printf("请输入顺序表的长度,不要超过最大长度:");
    scanf_s("%d", &n);
    printf("请输入%d个元素的值:",n);
    CreatList(L, n);//创建顺序表
	Reverse(L);//删除顺序表最小
    printf("逆序后的顺序表为:");
    for (int i = 0; i < L.length; i++) {
        printf("%d ", L.data[i]);
    }
    printf("\n");
    return 0;
}

运行结果

image.png

复杂度

  • 时间复杂度O(n)--- 遍历一半的顺序表,其中n为当前顺序表长度
  • 空间复杂度 O(1)--- 顺序表为必要空间,其次仅含常数级的辅助空间

34、删除顺序表中为x的元素

思路

用k记录顺序表中不等于x的元素个数(即要保存的元素个数),扫描时将不等于x的元素个数移动到下标k的位置,并更新k的值,扫描结束后更新顺序表的长度。

具体实现

#include<stdio.h>
#define MaxSize 100//顺序表最大长度
typedef struct	 {
	int data[MaxSize];
	int length;

//删除等于x的值
bool Delete_x(SqList& L,int x) {
	if (L.length == 0)return false;//顺序表为空
	int k = 0;//k用来记录不等于x的值
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] != x) {
			L.data[k] = L.data[i];//元素不等于x,则将其前移
			k++;//不等于x的元素加一	
		}
	}
	// 更新顺序表长度(可能有些x没有被删除,通过更新长度来实现的假删除)
	L.length = k;
	return true;
}
int main() {
	SqList L;
	int n;//创建顺序表的长度
	printf("请输入顺序表的长度,不要超过最大长度:");
	scanf_s("%d", &n);
	printf("请输入%d个元素的值:", n);
	CreatList(L, n);//创建顺序表
	printf("请输入要删除元素的值:");
	int x;
	scanf_s("%d", &x);
	Delete_x(L,x);//删除顺序表中为x的值
	printf("删除后的顺序表为:");
	for (int i = 0; i < L.length; i++) {
		printf("%d ", L.data[i]);
	}
	printf("\n");
	return 0;
}

运行结果

image.png

复杂度

  • 时间复杂度 O(n)--- 遍历整个顺序表找x,其中n为当前顺序表长度
  • 空间复杂度 O(1)--- 顺序表为必要空间,其次仅含常数级的辅助空间

运行结果

跟着大神代码敲打一遍,似乎有些东西又通透了