(C++)数据结构初阶(顺序表的实现)

发布于:2025-09-10 ⋅ 阅读:(14) ⋅ 点赞:(0)

顺序表的概念

        顺序表是数据结构中一种基础的线性存储结构,它用一段连续的内存空间依次存储数据元素,逻辑上相邻的元素在物理内存中也相邻。概念这部分就简单介绍下,重点是顺序表的实现方法

顺序表的实现方法

定义一个动态的顺序表结构

//定义动态顺序表结构
typedef int SLDataType;
typedef struct SeqList {
	SLDataType* arr;//指向动态数组分配的指针
	int capacity;  //空间大小
	int size;  //有效数据个数
}SL;

//typedef struct SeqList SL;

初始化动态顺序表(SeqList.h)

初始化·1

//初始化数据
void SLInit(SL* ps);
//销毁数据
void SLDataTroy(SL* ps);

初始化·2

//插入数据
//尾插
void SLPushBack(SL* ps, SLDataType x);
//头插
void SLPushFront(SL* ps, SLDataType x);

////判断空间是否足够
//void SLCheckCapacity(SL* ps);

//打印数据
void SLPrint(SL* ps);

初始化·3

//删除数据
//尾删
void SLPopBack(SL* ps);
//头删
void SLPopFront(SL* ps);

初始化·4

//指定位置插入数据
void SLInsert(SL* ps, SLDataType x, int pos);
//删除指定位置数据
void SLErase(SL* ps, int pos);
//查找数据
int SLFind(SL* ps, SLDataType x);

实现动态顺序表的函数方法(SeqList.cpp)

方法一

//初始化
void SLInit(SL* ps) {
	ps->arr = NULL;//指针指向空,初始不分配内存
	ps->size = ps->capacity = 0;
}
//销毁
void SLDataTroy(SL* ps) {
	if (ps->arr) {//判断是否有分配内存(即是否等于空)
		free(ps->arr);//释放动态分配的数组内存
	}
	ps->arr = NULL;// 避免野指针
	ps->size = ps->capacity = 0;
}

方法二

//判断空间是否足够
void SLCheckCapacity(SL* ps) {
	//判断空间是否充足
	if (ps->size == ps->capacity) {
		//增容(初始容量为0,则为4,否则翻倍)
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//重新分配内存,这里注意,申请内存空间时要使用realloc
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
		//处理内存分配失败
		if (tmp == NULL) {
			perror("realloc fail");//打印错误信息
			exit(1);//退出
		}
		//更新指针和容量
		ps->arr = tmp;
		ps->capacity *= newCapacity;
	}
}

//插入数据
//尾插(直接在size位置插入)
void SLPushBack(SL* ps, SLDataType x) {
	//断言
	assert(ps);
	////数据不为空
	//if (ps == NULL) {
	//	return;
	//}
	SLCheckCapacity(ps);//检查空间是否足够
	ps->arr[ps->size++] = x;
}
//头插(数据整体后移一位)
void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);//断言
	SLCheckCapacity(ps);//检查空间是否足够

	//数据整体后移一位
	for (int i = ps->size; i > 0; --i) {
		ps->arr[i] = ps->arr[i - 1];//方法
	}
	//下标为0的位置空出来了
	//更新元素以及个数
	ps->arr[0] = x;
	ps->size++;
}

//打印数据
void SLPrint(SL* ps) {
	for (int i = 0; i < ps->size; ++i) {
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}

方法三

//删除数据
//尾删(直接在size位置进行删除)
void SLPopBack(SL* ps) {
	assert(ps);//断言
	assert(ps->size > 0);//非NULL
	ps->arr[ps->size - 1] = -1;//方法
	ps->size--;
}
//头删(数据整体向前移动一位)
void SLPopFront(SL* ps) {
	assert(ps);//断言
	assert(ps->size>0);//非NULL
	
	//数据整体向前移动一位
	for (int i = 0; i < ps->size - 1; ++i) {
		ps->arr[i] = ps->arr[i + 1];//方法
	}
	ps->size--;
}

方法四

//指定位置插入数据
void SLInsert(SL* ps, SLDataType x, int pos) {
	assert(ps);//断言
	//在指定范围[0,size]插入数据,确保不越界
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);//检查空间是否足够
	//pos及之后的数据整体向后移动一位
	for (int i = ps->size; i > pos; --i) {
		ps->arr[i] = ps->arr[i - 1];//方法
	}
	//更新元素即个数
	ps->arr[pos] = x;
	ps->size++;
}
//删除指定位置数据
void SLErase(SL* ps, int pos) {
	assert(ps);//断言
	//在指定范围[0,size]插入数据,确保不越界
	assert(pos >= 0 && pos < ps->size);
	SLCheckCapacity(ps);//检查空间是否足够
	//顺序表不能为空
	//pos之后的数据整体向前移动一位
	for (int i = pos; i < ps->size-1; ++i) {
		ps->arr[i] = ps->arr[i + 1];//方法
	}
	ps->size--;
}
//查找数据
int SLFind(SL* ps, SLDataType x) {
	assert(ps);//断言
	for (int i = 0; i < ps->size; ++i) {
		if (ps->arr[i] == x) {//条件
			return i;
		}
	}
	//如果没有找到
	return -1;
}

测试动态顺序表的函数方法

        这里不重要,你们只需要知道怎么做就可以了!!!

#include"SeqList.h"
#include"STAP.h"
//#include"SeqList.cpp""

void SLtest01() {
	SL s;
	SLInit(&s);

	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);

	/*SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);*/

	/*SLPopBack(&s);
	SLPrint(&s);
	SLPopBack(&s);
	SLPrint(&s);
	SLPopBack(&s);
	SLPrint(&s);
	SLPopBack(&s);
	SLPrint(&s);*/

	/*SLPopBack(&s);
	SLPrint(&s);*/

	/*SLPopFront(&s);
	SLPrint(&s);
	SLPopFront(&s);
	SLPrint(&s);*/

	/*SLInsert(&s,5,0);
	SLPrint(&s);*/
	
	/*SLErase(&s, 3);
	SLPrint(&s);*/

	int find = SLFind(&s, 2);
	if (find < 0) {
		printf("没有数据");
	}
	else {
		printf("找到了");
	}
	
	SLDataTroy(&s);
}

void SLtest02() {

	printf("\n");
	//std::vector<int> nums[] = { 3,2,2,3,4,5,3 };
	///*int numSize = sizeof(nums) / sizeof(nums[0]);*/
	//int n = nums.size();
	//int val = 3;
	//int newSize = RemoveElement(nums, /*numSize,*/n, val);

	//printf("%d %d", val, newSize);

	//for (int i = 0; i < newSize; ++i) {
	//	printf("%d", nums[i]);
	//}

	std::vector<int> nums = { 3,2,2,3,4,5 };

	int val = 3;
	int newSize = RemoveElement(nums, val);

	/*cout << val << " " << newSize << endl;*/
	cout << val << "\n";
	cout << newSize << "\n";

	for (int i = 0; i < newSize; ++i) {
		cout << nums[i] << " ";
	}
}

void SLtest03() {

	printf("\n");
	vector<int> nums = { 1,1,2,2,3,4,4,5 };
	int n = nums.size();

	int newSize = removeDuplicates(nums, n);

	for (int i = 0; i < n; ++i) {
		cout << nums[i] << " ";
	}
	/*cout << "\n";*/
}

//void SLtest04() {
//	vector<int> nums1 = { 1,2,3,0,0,0 };
//	int m = 3;
//	vector<int> nums2 = { 2,5,6 };
//	int n = 3;
//
//	/*merge(nums1, m, nums2, n);*/
//
//	cde(nums1, m, nums2, n);
//
//	for (int num : nums1) {
//		cout << num << "\n";
//	}
//}

int main() {
	//顺序表
	/*SLtest01();*/

	//顺序表算法题:移除元素
	SLtest02();

	//顺序表算法题:删除有序数组中的重复项
	SLtest03();

	//顺序表算法题:合并两个有序数组
	/*SLtest03();*/
	return 0;
}

动态顺序表的三个拓展算法题

顺序表算法题:移除元素

题目描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。返回 k。

题目解析

思路:双指针算法(两个指针)
定义两个指针变量,指向数组第一个位置,
判断nums[src]是否等于val,如果相等,src++
如果不相等 nums[dst]=nums[src],src++,dst++;

时间复杂度:O(n)
空间复杂度:O(1)

解题代码

//算法:双指针算法

//int RemoveElement(int* nums, int numSize, int val) {
//	int src = 0, dst = 0;
//	while (src < numSize) {
//		if (nums[src] == val) {
//			src++;
//		}
//		else {
//			nums[dst++] = nums[src++];
//		}
//	}
//	return dst;
//}

int RemoveElement(vector<int>& nums, int val) {
	int n = nums.size();
	int l = 0, r = 0;
	while (r < n) {
		if (nums[r] == val) {
			++r;
		}
		else {
			nums[l++] = nums[r++];
		}
	}
	return l;
}

顺序表算法题:删除有序数组中的重复项

题目描述

        给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

        更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。返回 k 。
        判题标准:

        系统会用下面的代码来测试你的题解:

        int[] nums = [...]; // 输入数组
        int[] expectedNums = [...]; // 长度正确的期望答案

        int k = removeDuplicates(nums); // 调用

        assert k == expectedNums.length;
        for (int i = 0; i < k; i++) {
        assert nums[i] == expectedNums[i];
        }
        如果所有断言都通过,那么您的题解将被 通过。

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,
并且原数组 nums 的前两个元素被修改为 1, 2 。
不需要考虑数组中超出新长度后面的元素。


示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 ,
并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。
不需要考虑数组中超出新长度后面的元素。


提示:

1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 非严格递增 排列

题目解析

//思路:定义两个指针,dst指向第一个位置,src指向下一个位置,判断src和dst的位置
//如果相等:src++
//如果不相等:dst++,nums[dst]=nums[src],src++

题目代码

//class Solution {
//public:
//    int removeDuplicates(vector<int>& nums,int numSize) {
//        int dst = 0, src = dst + 1;
//        while (src < numSize) {
//            if (nums[dst] != nums[src]) {
//                dst++;
//                nums[dst] = nums[src];
//            }
//            src++;
//        }
//        return dst + 1;
//    }
//};

int removeDuplicates(vector<int>& nums, int numSize) {
    int dst = 0, src = dst + 1;
    while (src < numSize) {
        if (nums[dst] != nums[src]) {
            dst++;
            nums[dst] = nums[src];
        }
        src++;
    }
    return dst + 1;
}

顺序表算法题:合并两个有序数组

题目描述

        给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,
分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

        注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。


示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。


示例 3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。


        注意,因为 m = 0 ,所以 nums1 中没有元素。
nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。


提示:

nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109


进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?

题目代码

void cde(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    int l1 = m - 1;
    int l2 = n - 1;
    int l3 = m + n - 1;
    while (l1 >= 0 || l2 >= 0) {
        if (nums1[l1] > nums2[l2]) {
            nums1[l3--] = nums1[l1--];
        }
        else {
            nums1[l3--] = nums2[l2--];
        }
    }
    while (l2 > 0) {
        nums1[l3--] = nums1[l2--];
    }
}

拓展

SeqList.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<assert.h>
using namespace std;


//定义动态顺序表结构
typedef int SLDataType;
typedef struct SeqList {
	SLDataType* arr;//指向动态数组分配的指针
	int capacity;  //空间大小
	int size;  //有效数据个数
}SL;

//typedef struct SeqList SL;

//初始化数据
void SLInit(SL* ps);
//销毁数据
void SLDataTroy(SL* ps);
//插入数据
//尾插
void SLPushBack(SL* ps, SLDataType x);
//头插
void SLPushFront(SL* ps, SLDataType x);

////判断空间是否足够
//void SLCheckCapacity(SL* ps);

//打印数据
void SLPrint(SL* ps);

//删除数据
//尾删
void SLPopBack(SL* ps);
//头删
void SLPopFront(SL* ps);

//指定位置插入数据
void SLInsert(SL* ps, SLDataType x, int pos);
//删除指定位置数据
void SLErase(SL* ps, int pos);
//查找数据
int SLFind(SL* ps, SLDataType x);

SeqList.cpp

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
#include"SeqList.h"
//初始化
void SLInit(SL* ps) {
	ps->arr = NULL;//指针指向空,初始不分配内存
	ps->size = ps->capacity = 0;
}
//销毁
void SLDataTroy(SL* ps) {
	if (ps->arr) {//判断是否有分配内存(即是否等于空)
		free(ps->arr);//释放动态分配的数组内存
	}
	ps->arr = NULL;// 避免野指针
	ps->size = ps->capacity = 0;
}

//判断空间是否足够
void SLCheckCapacity(SL* ps) {
	//判断空间是否充足
	if (ps->size == ps->capacity) {
		//增容(初始容量为0,则为4,否则翻倍)
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//重新分配内存,这里注意,申请内存空间时要使用realloc
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
		//处理内存分配失败
		if (tmp == NULL) {
			perror("realloc fail");//打印错误信息
			exit(1);//退出
		}
		//更新指针和容量
		ps->arr = tmp;
		ps->capacity *= newCapacity;
	}
}

//插入数据
//尾插(直接在size位置插入)
void SLPushBack(SL* ps, SLDataType x) {
	//断言
	assert(ps);
	////数据不为空
	//if (ps == NULL) {
	//	return;
	//}
	SLCheckCapacity(ps);//检查空间是否足够
	ps->arr[ps->size++] = x;
}
//头插(数据整体后移一位)
void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);//断言
	SLCheckCapacity(ps);//检查空间是否足够

	//数据整体后移一位
	for (int i = ps->size; i > 0; --i) {
		ps->arr[i] = ps->arr[i - 1];//方法
	}
	//下标为0的位置空出来了
	//更新元素以及个数
	ps->arr[0] = x;
	ps->size++;
}

//打印数据
void SLPrint(SL* ps) {
	for (int i = 0; i < ps->size; ++i) {
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}

//删除数据
//尾删(直接在size位置进行删除)
void SLPopBack(SL* ps) {
	assert(ps);//断言
	assert(ps->size > 0);//非NULL
	ps->arr[ps->size - 1] = -1;//方法
	ps->size--;
}
//头删(数据整体向前移动一位)
void SLPopFront(SL* ps) {
	assert(ps);//断言
	assert(ps->size>0);//非NULL
	
	//数据整体向前移动一位
	for (int i = 0; i < ps->size - 1; ++i) {
		ps->arr[i] = ps->arr[i + 1];//方法
	}
	ps->size--;
}

//指定位置插入数据
void SLInsert(SL* ps, SLDataType x, int pos) {
	assert(ps);//断言
	//在指定范围[0,size]插入数据,确保不越界
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);//检查空间是否足够
	//pos及之后的数据整体向后移动一位
	for (int i = ps->size; i > pos; --i) {
		ps->arr[i] = ps->arr[i - 1];//方法
	}
	//更新元素即个数
	ps->arr[pos] = x;
	ps->size++;
}
//删除指定位置数据
void SLErase(SL* ps, int pos) {
	assert(ps);//断言
	//在指定范围[0,size]插入数据,确保不越界
	assert(pos >= 0 && pos < ps->size);
	SLCheckCapacity(ps);//检查空间是否足够
	//顺序表不能为空
	//pos之后的数据整体向前移动一位
	for (int i = pos; i < ps->size-1; ++i) {
		ps->arr[i] = ps->arr[i + 1];//方法
	}
	ps->size--;
}
//查找数据
int SLFind(SL* ps, SLDataType x) {
	assert(ps);//断言
	for (int i = 0; i < ps->size; ++i) {
		if (ps->arr[i] == x) {//条件
			return i;
		}
	}
	//如果没有找到
	return -1;
}

STAP.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<assert.h>
using namespace std;

//移除元素
//int RemoveElement(int* nums,int newSize, int val);

// 函数声明
int RemoveElement(std::vector<int>& nums, int val);

////删除有序数组中的重复项
//int removeDuplicates(vector<int>& nums, int numSize)

int removeDuplicates(vector<int>& nums, int numSize);

T_ele.cpp

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
#include"STAP.h"

//顺序表算法题:移除元素

/*
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。
元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。
nums 的其余元素和 nums 的大小并不重要。
返回 k。
*/

/*
思路:双指针算法(两个指针)
定义两个指针变量,指向数组第一个位置,
判断nums[src]是否等于val,如果相等,src++
如果不相等 nums[dst]=nums[src],src++,dst++;

时间复杂度:O(n)
空间复杂度:O(1)

*/

//算法:双指针算法

//int RemoveElement(int* nums, int numSize, int val) {
//	int src = 0, dst = 0;
//	while (src < numSize) {
//		if (nums[src] == val) {
//			src++;
//		}
//		else {
//			nums[dst++] = nums[src++];
//		}
//	}
//	return dst;
//}

int RemoveElement(vector<int>& nums, int val) {
	int n = nums.size();
	int l = 0, r = 0;
	while (r < n) {
		if (nums[r] == val) {
			++r;
		}
		else {
			nums[l++] = nums[r++];
		}
	}
	return l;
}

R_doa.cpp

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)

#include"STAP.h"

//顺序表算法题:删除有序数组中的重复项

/*
给你一个 非严格递增排列 的数组 nums ,
请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,
返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,
你需要做以下事情确保你的题解可以被通过:

更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,
并按照它们最初在 nums 中出现的顺序排列。
nums 的其余元素与 nums 的大小不重要。返回 k 。
判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。



示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,
并且原数组 nums 的前两个元素被修改为 1, 2 。
不需要考虑数组中超出新长度后面的元素。
示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 ,
并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。
不需要考虑数组中超出新长度后面的元素。


提示:

1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 非严格递增 排列
*/

//思路:定义两个指针,dst指向第一个位置,src指向下一个位置,判断src和dst的位置
//如果相等:src++
//如果不相等:dst++,nums[dst]=nums[src],src++


//class Solution {
//public:
//    int removeDuplicates(vector<int>& nums,int numSize) {
//        int dst = 0, src = dst + 1;
//        while (src < numSize) {
//            if (nums[dst] != nums[src]) {
//                dst++;
//                nums[dst] = nums[src];
//            }
//            src++;
//        }
//        return dst + 1;
//    }
//};

int removeDuplicates(vector<int>& nums, int numSize) {
    int dst = 0, src = dst + 1;
    while (src < numSize) {
        if (nums[dst] != nums[src]) {
            dst++;
            nums[dst] = nums[src];
        }
        src++;
    }
    return dst + 1;
}

M_arrays.cpp

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
#include"STAP.h"

//顺序表算法题:合并两个有序数组

/*
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,
分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。
为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,
后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。



示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。
示例 3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。
nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。


提示:

nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109


进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?
*/


void cde(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    int l1 = m - 1;
    int l2 = n - 1;
    int l3 = m + n - 1;
    while (l1 >= 0 || l2 >= 0) {
        if (nums1[l1] > nums2[l2]) {
            nums1[l3--] = nums1[l1--];
        }
        else {
            nums1[l3--] = nums2[l2--];
        }
    }
    while (l2 > 0) {
        nums1[l3--] = nums1[l2--];
    }
}

test.cpp

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
#include"SeqList.h"
#include"STAP.h"
//#include"SeqList.cpp""

void SLtest01() {
	SL s;
	SLInit(&s);

	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);

	/*SLPushFront(&s, 1);
	SLPushFront(&s, 2);
	SLPushFront(&s, 3);
	SLPushFront(&s, 4);*/

	/*SLPopBack(&s);
	SLPrint(&s);
	SLPopBack(&s);
	SLPrint(&s);
	SLPopBack(&s);
	SLPrint(&s);
	SLPopBack(&s);
	SLPrint(&s);*/

	/*SLPopBack(&s);
	SLPrint(&s);*/

	/*SLPopFront(&s);
	SLPrint(&s);
	SLPopFront(&s);
	SLPrint(&s);*/

	/*SLInsert(&s,5,0);
	SLPrint(&s);*/
	
	/*SLErase(&s, 3);
	SLPrint(&s);*/

	int find = SLFind(&s, 2);
	if (find < 0) {
		printf("没有数据");
	}
	else {
		printf("找到了");
	}
	
	SLDataTroy(&s);
}

void SLtest02() {

	printf("\n");
	//std::vector<int> nums[] = { 3,2,2,3,4,5,3 };
	///*int numSize = sizeof(nums) / sizeof(nums[0]);*/
	//int n = nums.size();
	//int val = 3;
	//int newSize = RemoveElement(nums, /*numSize,*/n, val);

	//printf("%d %d", val, newSize);

	//for (int i = 0; i < newSize; ++i) {
	//	printf("%d", nums[i]);
	//}

	std::vector<int> nums = { 3,2,2,3,4,5 };

	int val = 3;
	int newSize = RemoveElement(nums, val);

	/*cout << val << " " << newSize << endl;*/
	cout << val << "\n";
	cout << newSize << "\n";

	for (int i = 0; i < newSize; ++i) {
		cout << nums[i] << " ";
	}
}

void SLtest03() {

	printf("\n");
	vector<int> nums = { 1,1,2,2,3,4,4,5 };
	int n = nums.size();

	int newSize = removeDuplicates(nums, n);

	for (int i = 0; i < n; ++i) {
		cout << nums[i] << " ";
	}
	/*cout << "\n";*/
}

//void SLtest04() {
//	vector<int> nums1 = { 1,2,3,0,0,0 };
//	int m = 3;
//	vector<int> nums2 = { 2,5,6 };
//	int n = 3;
//
//	/*merge(nums1, m, nums2, n);*/
//
//	cde(nums1, m, nums2, n);
//
//	for (int num : nums1) {
//		cout << num << "\n";
//	}
//}

int main() {
	//顺序表
	/*SLtest01();*/

	//顺序表算法题:移除元素
	SLtest02();

	//顺序表算法题:删除有序数组中的重复项
	SLtest03();

	//顺序表算法题:合并两个有序数组
	/*SLtest03();*/
	return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到